ISEE小语
本次主要使用的三方库是MechanicalSoup和openpyxl。MechanicalSoup用来爬虫数据,openpyxl用来将数据写入Excel。以下先简单了解一下这两个三方库。
MechanicalSoup 是一个基于 Python 的库,它提供了一个简单的 API 来自动化与网页的交云,并且结合了 Requests 和 BeautifulSoup 的功能。MechanicalSoup 被设计用来模拟浏览器的行为,使得用户能够像在浏览器中一样执行各种网页操作,例如填写表单,点击按钮等。
MechanicalSoup 最初是作为另一个 Python 库 Mechanical Turk 的一个替代品而存在的,Mechanical Turk 不再被维护。MechanicalSoup 之所以受欢迎,是因为它既继承了 Mechanical Turk 的易用性,又整合了 Requests 和 BeautifulSoup 的强大功能。
openpyxl 是一个 Python 库,用于读取和写入xlsx/xlsm/xltx/xltm文件。它提供了创建和修改 Excel 文档的工具。
环境:
Pycharm
Python 3.9.16
安装:
pip install MechanicalSoup==1.3.0
pip install openpyxl==3.1.2
注:爬虫需要的包,没有的话可以去自行下载。直接用pip安装即可。
导入:
import mechanicalsoup
from openpyxl.workbook import Workbook
(左右滑动查看完整代码)
1 网站地址
首先,先确定网站地址
# 网站地址
base_url = 'https://www.douban.com'
(左右滑动查看完整代码)
再找到【排行榜】标题,点击进入排行榜页面。
本次就是将排行榜的信息爬取出来,然后保存到Excel中。
2 头信息
头信息,即headers信息
# 设置浏览器头信息
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
'Referer': 'https://www.douban.com'
}
(左右滑动查看完整代码)
headers可以在浏览器中获取,打开浏览器,按下F12键,输入网站链接,在Network中可以看到。
3 创建会话对象
创建一个Browser对象
# 创建一个Browser对象
browser = mechanicalsoup.Browser()
browser.session.headers.update(headers)
(左右滑动查看完整代码)
确定排行榜页面的Url,获取排行榜的信息
# 使用浏览器对象打开链接
url = "https://movie.douban.com/chart"
page = browser.get(url)
(左右滑动查看完整代码)
4 获取页面内容
获取【排行榜】首页的页面内容,并保存在一个列表中
# 通过CSS选择器查找并获取href值
soup = page.soup
tables = soup.find_all('table')
# 创建一个列表来存储所有表格的内容
table_contents = []
# 遍历所有的<table>标签
for table in tables:
# 创建一个字典来存储电影的详细信息
movie_details = {'title': table.find('a', class_='nbg')['title'], # 获取页面的title
'img_url': table.find('img', width='75')['src'], # 获取图片的URL
'description': table.find('p', class_='pl').text.strip(), # 获取描述内容
'rating_nums': table.find('span', class_='rating_nums').text, # 评分
'rating_people': table.find('span', class_='pl').text, # 评价人数
}
table_contents.append(movie_details)
print(table_contents)
(左右滑动查看完整代码)
结果:
数据已经爬取出来了,那么接下来就可以进行Excel写入了,我们保存的格式是:
注意:在爬取图片写入的时候,需要用到pillow三方库做辅助,如果没有则直接安装即可。
pip install pillow==10.2.0
5 写入Excel
创建一个工作簿,激活第一个工作表
# 创建一个工作簿
wb = Workbook()
# 激活第一个工作表
ws = wb.active
(左右滑动查看完整代码)
设置Excel中的列名
ws.append(["Image", "Title", "Description", "Rating_nums", "Evaluation_nums"])
(左右滑动查看完整代码)
下载图片并插入排行榜所有对应信息
# 下载图片并插入excel第一列
image_file = None
# 变量来定义图片大小
img_width = 150
img_height = 150
for index, movie in enumerate(table_contents, start=2): # start=2是因为第一行已经被列名占据
# 下载图片
response = requests.get(movie["img_url"])
if response.status_code == 200:
# 将响应内容包装成BytesIO对象,这样就可以直接读取为图片
image_file = BytesIO(response.content)
# 使用openpyxl插入图片
img = Image(image_file)
# 设置图片的大小
aspect_ratio = img.width / img.height
new_height = img_height # 设置新的高度
new_width = int(aspect_ratio * new_height) # 计算新的宽度以保持图片比例
img.width, img.height = new_width, new_height # 调整图片尺寸
# 添加图片到工作表
cell_ref = f'A{index}'
ws.add_image(img, cell_ref)
# 设置行高为图片高度
point_height = new_height * 0.75 # Excel的行高是以点为单位的,1点等于1/72英寸
ws.row_dimensions[index].height = point_height
# 写入其余数据
ws.append([None, movie["title"], movie["description"], movie["rating_nums"], movie["rating_people"]])
(左右滑动查看完整代码)
为了适应图片的大小,需要设置一下第一列的宽度
ws.column_dimensions['A'].width = img_width / 7
(左右滑动查看完整代码)
最后保存工作簿并关闭对象
# 保存工作簿
wb.save("movies_ranking.xlsx")
wb.close()
# 关闭BytesIO对象
image_file.close()
(左右滑动查看完整代码)
运行完成后,在当前目录下会自动生成一个movies_ranking.xlsx文件,双击打开,结果如下:
6 最终代码整理
# -*- coding: utf-8 -*-
from openpyxl.drawing.image import Image
from io import BytesIO
import mechanicalsoup
import requests
from openpyxl.workbook import Workbook
# 设置浏览器头信息
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
'Referer': 'https://www.douban.com'
}
# 创建一个Browser对象
browser = mechanicalsoup.Browser()
browser.session.headers.update(headers)
# 使用浏览器对象打开链接
url = "https://movie.douban.com/chart"
page = browser.get(url)
# 通过CSS选择器查找并获取href值
soup = page.soup
tables = soup.find_all('table')
# 创建一个列表来存储所有表格的内容
table_contents = []
# 遍历所有的<table>标签
for table in tables:
# 创建一个字典来存储电影的详细信息
movie_details = {'title': table.find('a', class_='nbg')['title'], # 获取页面的title
'img_url': table.find('img', width='75')['src'], # 获取图片的URL
'description': table.find('p', class_='pl').text.strip(), # 获取描述内容
'rating_nums': table.find('span', class_='rating_nums').text, # 评分
'rating_people': table.find('span', class_='pl').text, # 评价人数
}
table_contents.append(movie_details)
print(table_contents)
# 创建一个工作簿
wb = Workbook()
# 激活第一个工作表
ws = wb.active
# 设置列名
ws.append(["Image", "Title", "Description", "Rating_nums", "Evaluation_nums"])
# 下载图片并插入excel第一列
image_file = None
# 变量来定义图片大小
img_width = 150
img_height = 150
for index, movie in enumerate(table_contents, start=2): # start=2是因为第一行已经被列名占据
# 下载图片
response = requests.get(movie["img_url"])
if response.status_code == 200:
# 将响应内容包装成BytesIO对象,这样就可以直接读取为图片
image_file = BytesIO(response.content)
# 使用openpyxl插入图片
img = Image(image_file)
# 设置图片的大小
aspect_ratio = img.width / img.height
new_height = img_height # 设置新的高度
new_width = int(aspect_ratio * new_height) # 计算新的宽度以保持图片比例
img.width, img.height = new_width, new_height # 调整图片尺寸
# 添加图片到工作表
cell_ref = f'A{index}'
ws.add_image(img, cell_ref)
# 设置行高为图片高度
point_height = new_height * 0.75 # Excel的行高是以点为单位的,1点等于1/72英寸
ws.row_dimensions[index].height = point_height
# 写入其余数据
ws.append([None, movie["title"], movie["description"], movie["rating_nums"], movie["rating_people"]])
# 调整第一列的列宽以适应图片宽度
ws.column_dimensions['A'].width = img_width / 7
# 保存工作簿
wb.save("movies_ranking.xlsx")
wb.close()
# 关闭BytesIO对象
image_file.close()
(左右滑动查看完整代码)
7 总结
以上实例仅限个人观点,学习使用。
寄语:世间三美,明月,清风,眼前……
看到这儿的朋友帮点个“赞”和“在看”,谢谢支持~!
文章就分享到这儿,喜欢就点个赞吧!