前言
善始者繁多,克终者盖寡。
前些日子分享了一种使用Selenium爬取MOOC课程评论的文章,但是那个操作中并未涉及图片、视频等类型文件的操作,今天和大家分享使用经典的爬虫方法爬取网站上的图片和文字。
一、爬虫与B/S模式
该内容可以参看之前的博客:Selenium实现MOOC课程评论自动爬取
简而言之,可以将爬虫理解为让程序模拟浏览器向目标地址发送请求,再从对方返回的信息中获取自己想要的文字、图片、视频等内容。
二、任务分解
Selenium是一个很智能的测试框架,我们只需要加载对应浏览器驱动,程序就能够启动对应浏览器完成相应任务。但是使用request时并没有这么智能,我们可以将爬取任务分为以下几个环节:
①目标地址;
②浏览器请求信息(作用是模拟浏览器);
③接收并解析服务器的响应(response),找到想要爬取的图片和文字;
④保存文字;
⑤保存图片。
三、代码实现
3.1 准备目标地址与请求信息
准备目标地址时需要仔细观察对应网站网页的结构,示例代码中将想要爬取的5个页面使用列表存起来,同时模拟火狐浏览器向对应地址发送请求。
提示:header可以在浏览器的请求头中找到,以火狐浏览器为例,可以在网页右键后依次点击“检查-网络”找到浏览器的请求头
urls = []
for index in range(1,6):
url = f"https://www.qidian.com/rank/yuepiao/year2022-month10-page{index}/"
urls.append(url)
header = r"{User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:106.0) Gecko/20100101 Firefox/106.0}"
3.2 解析页面
接收到对方的返回信息后,使用PyQuery(类似于JQuery)进行解析。
文字性内容处理起来简单,直接通过分词取出即可;
获取到的图片对象包含“src”和“alt”两个属性,“src”存储了图片的网络地址,可以使用此地址下载图片,“alt”是对图片的描述说明,可根据个人需求取舍,此处舍去“alt”属性内容。
name = []
author = []
imgs = []
for url in urls:
rep = req.get(url,header)
# 将Response对象转换为PyQuery对象
query = PyQuery(rep.text)
name_t = query("h2 a").text().split(" ")
author_t = query("p.author a.name").text().split(" ")
img = query("div.book-img-box img")
for item in img.items():
imgs.append(item.attr("src"))
# imgsrc = query("div.book-img-box img").attr("src")
# print(imgsrc)
name.extend(name_t)
author.extend(author_t)
3.3 保存文字
文字内容无需特别处理,直接通过DataFrame保存为excel或者csv文件即可。
df = pandas.DataFrame(name,columns=["书名"])
df["作者"]=author
# df.to_csv("books.csv")
df.to_excel("books.xlsx")
3.4 下载图片
所有的图片链接都存放在3.2中得到的“imgs”中,遍历列表获取每一张图片的url,使用request从对应的url里下载图片。
注意:文件操作完毕后记得关闭文件的输入、输出流。
for i in range(len(imgs)):
imgname =f"imgs/{i}.jpg"
url = "https:"+imgs[i]
rep = req.get(url,stream=True)
with open(imgname,"wb") as imf:
# 使用二进制流的方式下载图片,下载完毕后需要手动关闭流
for nodes in rep:
imf.write(nodes)
imf.close()
print(imgs)
三、程序测试
浏览器信息以及拟爬取地址信息已经在“get_author_bookname”方法中写死,此处只调用该方法即可。
3.1测试代码
import requests as req
from bs4 import BeautifulSoup as bea
from pyquery import PyQuery
import pandas
if __name__ == '__main__':
get_author_bookname()
3.2 运行结果
3.3 个人观点
使用request模拟浏览器向目标地址发送请求,这种方法不能够让人直观的看到任务执行的过程(没有可视化的界面),相较之下,Selenium就好了很多。