项目案例实现|Python爬虫 05:爬取糗事百科上的热图
项目来源
本项目来源B站UP主路飞学城视频:视频链接点这里
项目需求
爬取糗事百科的热图(使用正则解析)
具体分析
1. 页面数据获取
与之前的项目不同,本项目将使用聚焦爬虫的方法,并用数据解析中的正则解析完成,达到熟悉正则解析的使用流程的目的。
打开糗事百科热图页的URL:https://www.qiushibaike.com/imgrank/,对此页面发请求拿到整张页面的源码数据。
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
} # UA伪装
url = 'https://www.qiushibaike.com/imgrank/'
# 发送请求
page_text = requests.get(url=url, headers=headers).text
2. 对想要的数据进行正则解析
通过对需求的分析,此时我们需要解析出的是热图的URL地址。在当前页面中打开抓包工具,对element板块中的整张页面的源码数据进行分析,定位到糗图的img标签在源码中的位置如下:
编写正则表达式(有不懂正则的小伙伴欢迎去看原视频,up主有讲解):
ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>' # 正则表达式
img_src_list = re.findall(ex, page_text, re.S) # 进行正则解析
至此,我们通过编写正则表达式实现了聚焦爬虫,即可以拿到热图对应的src属性值
3. 爬取图片数据
到此为止我们获得了图片的src属性值,但通过观察我们发现,此src属性值并不是完整的图片地址,缺少一个协议头。在element板块中点击一张热图,点击复制链接地址,即可看到完整的地址,我们将这张图片的地址粘贴至此:https://pic.qiushibaike.com/system/pictures/12401/124011687/medium/B90X13RUTJXVQZRP.jpg
,可以发现协议头为https,故将https拼接到解析出的src字符串中,因为一张页面中所有图片的src属性值存储于一个列表中,故用for循环遍历即可完成所有地址的拼接。
for src in img_src_list:
src = 'https:' + src # 拼接完整URL地址
img_data = requests.get(url=src, headers=headers).content # 获取图片数据
因为图片的数据形式为二进制数据,故需要以content形式存储。
4.持久化存储
因为爬取的数据为图片,有多张,此处直接存储在本地不太合适。可以新建文件夹存储,需调用os模块,具体操作如下:
import os
if not os.path.exists('./糗图'):
os.mkdir('./糗图')
文件夹建好后,就可以一一将图片写入文件夹内:
fileName = src.split('/')[-1] # 用图片地址中以'/'为分割符分割后得到的列表中最后一个元素为文件名
file_path = './糗图/' + fileName
with open(file_path, 'wb') as fp: # 二进制数据写入关键字为'wb'
fp.write(img_data)
至此,本项目需求已基本实现!
5. 分页操作
下面进行分页操作,将2~4页页面URL地址粘贴如下:
- https://www.qiushibaike.com/imgrank/page/2/
- https://www.qiushibaike.com/imgrank/page/3/
- https://www.qiushibaike.com/imgrank/page/4/
对比可发现,只有后面的数字区别,而后面的数字表示当前页面为第几页,那么只用动态改变后面数字的值即可实现分页操作,通过代码编写可实现全部页码的图片数据爬取,具体在完整代码中展示。
项目代码
# -*- coding: utf-8 -*-
# @author : QIN
# @time : 2021/1/13 22:06
# @function :
import os
import re
import requests
if __name__ == '__main__':
header = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'
}
# 创建文件夹,用来保存所有的图片
if not os.path.exists('./糗图'):
os.mkdir('./糗图')
# 分页操作
get_url = 'https://www.qiushibaike.com/imgrank/page/%d/'
for page_num in range(1, 14):
full_url = format(get_url % page_num)
page_text = requests.get(url=full_url, headers=header).text
# 使用聚焦爬虫将页面中所有的糗图进行解析/提取
ex = '<div class="thumb">.*?<img src="(.*?)" alt.*?</div>'
img_src_list = re.findall(ex, page_text, re.S)
for src in img_src_list:
# 拼接完整的URL图片地址
src = 'https:' + src
img_data = requests.get(url=src, headers=header).content
filename = src.split('/')[-1]
img_path = './糗图/' + filename
with open(img_path, 'wb') as fp:
fp.write(img_data)
print('{}下载成功'.format(filename))
运行结果
可见全部页码的全部图片都已爬取到位,即本案例完成!
注意事项
- 需要发送两次请求,其中第一次请求的目的为获取图片地址,第二次才是爬取图片数据
- 图片数据的存储形式为二进制,与文字等不同,需用content而不是text
- 当所需要获取的图片数据量过大时,可将数据存储至文件夹中