(Scrapy框架) 行百里者半九十(5)
Scrapy框架图片爬取实现
-
- 需求
-
图片数据采集中的ImagesPipeline模块
-
- 基于scrapy框架的图片抓取
- ImagesPipeline功能组件
- 实施步骤
-
重要提示
-
程序编码实现
-
执行后的输出结果
-
- 需求
需求
获取站长素材中的图片
图片数据爬取之ImagesPipeline
Scrapy框架图片爬取实现
通过 xpath 提取图片 src 属性的值,并针对该地址单独发送请求,以获取图片对应的二进制数据内容。
ImagesPipeline功能解析
只需对 img 标签中 src 属性所包含的信息进行提取,并将其传递至处理流程,该流程将自动发起对图片源地址的访问请求,获取对应的二进制数据并完成长期存储操作。
使用流程概述
-
数据解析(获取图片的存储路径)
-
将包含存储路径的 item 提交至指定的管道类
-
在管道文件中,自定义了一个继承自
ImagesPipeLine的管道类
— 函数方法get_media_request负责发送请求
— 函数方法file_path用于自定义图片的命名规则
— 函数方法item_completed将 item 转发至后续执行的管道类 -
在配置文件中设置以下内容:
— 确定图片存储的具体位置:IMAGES_STORE = "./photo"
— 指明启用的管道:自定义开发的管道类
注意事项概述
在利用 xpath 对图片地址进行解析的过程中,发现所获取到的地址内容为空。
主文件如下:
import scrapy
class PhotoSpider(scrapy.Spider):
name = 'photo'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://sc.chinaz.com/tupian/']
def parse(self, response):
src_list = response.xpath('//div[@id="container"]/div/div/a/img/@src').extract()
print(src_list)
for src in src_list:
src = "https:" + src
print(src)

这究竟是什么原因造成的呢?
当我们访问网页并查看其代码时,可以发现这些图片链接所归属的属性存在两种不同的形式,分别为 src 与 src2。


那么这两种方式之间存在哪些差异呢?
当我们展开检查代码的下拉菜单界面后可以注意到,一旦图片进入可视区域,其属性便会由 src2 转换为 src 。
因此,在进行数据爬取并采用 xpath 进行解析时,应当优先选择 src2 属性作为提取目标。
主文件
import scrapy
from photopro.items import PhotoproItem
import re
class PhotoSpider(scrapy.Spider):
name = 'photo'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://sc.chinaz.com/tupian/']
def parse(self, response):
src_list = response.xpath('//div[@id="container"]/div/div/a/img/@src2').extract()
for src in src_list:
src = "https:" + src
print(src)

通过点击详情页面查看图片,我们注意到所获取的链接仅为缩略图,而原图的地址与获取到的链接相比,仅多了一个_s后缀。
所爬取的链接为 https://scpic3.chinaz.net/Files/pic/pic9/202107/bpic23822_s.jpg
高清图片对应的链接为 https://scpic3.chinaz.net/Files/pic/pic9/202107/bpic23822.jpg
🆗,在掌握上述两点需要注意的事项后,接下来就可以开始编写代码了。
代码实现
自定义管道类 pipelines.py
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
# useful for handling different item types with a single interface
from itemadapter import ItemAdapter
# class PhotoproPipeline:
# def process_item(self, item, spider):
# return item
import scrapy
from scrapy.pipelines.images import ImagesPipeline
class ImgPipeline(ImagesPipeline):
# 对 item 中的图片进行请求操作
def get_media_requests(self, item, info):
yield scrapy.Request(url = item["src"])
# 定制图片的名称
def file_path(self, request, response = None, info = None):
url = request.url
file_name = url.split("/")[-1]
return file_name
def item_completed(self, result, item, info):
return item # 该返回值会传递给下一个即将被执行的管道类
items.py 的代码内容
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class PhotoproItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
src = scrapy.Field()
pass
主程序代码
import scrapy
from photopro.items import PhotoproItem
import re
class PhotoSpider(scrapy.Spider):
name = 'photo'
# allowed_domains = ['www.xxx.com']
start_urls = ['https://sc.chinaz.com/tupian/']
def parse(self, response):
src_list = response.xpath('//div[@id="container"]/div/div/a/img/@src2').extract()
for src in src_list:
src = "https:" + src
src = re.sub("_s", "", src)
item = PhotoproItem()
item["src"] = src
# print(src)
yield item
设置文件


在 photopro.pipelines.ImgPipeline 中,photopro.pipelines. 后所填写的内容必须为先前自行定义的管道类。
运行结果展示


