图片数据爬取之ImagesPipeline
-
基于scrapy爬取字符串类型的数据和爬取图片类型的数据的区别?
- 字符串:只需要基于xpath进行解析且提交管道进行持久化存储
- 图片:xpath解析出图片src的属性值。单独的对图片地址发起请求获取图片二进制类型的数据
-
ImagesPipeline:
- 需要将img的src的属性值进行解析,提交到管道,管道就会对图片的src进行请求发送获取图片的二进制类型的数据,且还会进行持久化存储
-
需求:爬取站长素材中的高清图片
网页中的图片使用了懒加载方式,所以解析时需要使用伪属性
-
使用流程:
-
数据解析(图片的地址)
[items.py]
import scrapy class ImgsproItem(scrapy.Item): # define the fields for your item here like: # name = scrapy.Field() img_src = scrapy.Field()
[chinaz.py]
import scrapy from imgsPro.items import ImgsproItem class ChinazSpider(scrapy.Spider): name = 'chinaz' # allowed_domains = ['www.xxx.com'] start_urls = ['http://sc.chinaz.com/tupian/'] def parse(self, response): div_list = response.xpath('//*[@id="container"]/div') for div in div_list: # 注意:使用伪属性 img_src = div.xpath('./div/a/img/@src2').extract_first() # print(img_src) item = ImgsproItem() item['img_src'] = img_src yield item
-
将存储图片地址的item提交到指定的管道类
[pipelines.py]from itemadapter import ItemAdapter # class ImgsproPipeline: # def process_item(self, item, spider): # return item import scrapy from scrapy.pipelines.images import ImagesPipeline class ImgsPipeline(ImagesPipeline): """ 类说明:自定义的专用于图片下载的管道类 """ def get_media_requests(self, item, info): """ 函数说明:根据图片地址进行图片数据的请求 :param item: :param info: :return: """ # 这里因为获取的是二进制数据,所以不需要 callback回调请求 yield scrapy.Request(item['img_src']) def file_path(self, request, response=None, info=None, *, item=None): """ 函数说明:指定图片存储的路径 :param request: :param response: :param info: :param item: :return: """ imgName = request.url.split('/')[-1] return imgName def item_completed(self, results, item, info): return item # 返回给下一个即将被执行的管道类
-
在管道文件中定制一个基于ImagesPipeline的管道类
- get_media_requests()
- file_path()
- item_completed()
-
在配置文件中
-
指定图片存储的目录:IMAGES_STORE = ‘./imgs’
-
指定开启的管道:自定义的管道类
-
-
Good Luck!
运行报错:
builtins.ModuleNotFoundError: No module named ‘PIL’
安装pillow模块:pip install pillow