赞
踩
我们知道使用requests与selenium下载图片都是非常简单的,那么scrapy是怎么下载图片的呢?
pip install pillow
# 设置请求头
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.0.0 Safari/537.36'
}
思路:
抓取到详情页中图片的url地址,交给图片管道进行下载
import scrapy from urllib.parse import urljoin class ImgSpider(scrapy.Spider): name = "img" allowed_domains = ["抓取的网站域名"] start_urls = ["抓取的起始网址"] def parse(self, response, **kwargs): # 抓取到每个详情页的url href_list = response.xpath('//ul[@class="pic-list2 clearfix"]/li/a/@href').extract() for href in href_list: # 去除不要的exe的url if href.find('exe') != -1: continue # 拼接url 获取到详情页的url detail_url = urljoin("http://desk.zol.com.cn/dongman/", href) # print(detail_url) # 请求详情页的url yield scrapy.Request(url=detail_url, callback=self.parse_detail) # 解析详情返回的响应对象 def parse_detail(self, response): # 获取详情页中不同分辨率大小的图片的url detail_href = response.xpath('//dd[@id="tagfbl"]/a/@href').extract() # print(detail_href) if len(detail_href) > 1: # 拼接大图的url max_img_url = urljoin("http://desk.zol.com.cn/dongman/", detail_href[0]) # print(max_img_url) # 请求大图页的url yield scrapy.Request(url=max_img_url, callback=self.parse_max_img) # 最后解析大图的url地址 def parse_max_img(self, response): url = response.xpath('//img[1]/@src').extract_first() print(url) yield {'img_src': url}
存储图片不能再像上篇文章一样,只用之前的管道类(pipeline),我们需要用到新的存储图片的管道类ImagesPipeline
from scrapy.pipelines.images import ImagesPipeline
from itemadapter import ItemAdapter from scrapy.pipelines.images import ImagesPipeline import scrapy class DeskPipeline(): def process_item(self, item, spider): return item class ImgPipeline(ImagesPipeline): # 1. 发送请求(下载图片, 文件, 视频,xxx) def get_media_requests(self, item, info): # 获取到图片的url url = item['img_src'] # 进行请求 yield scrapy.Request(url=url, meta={"url": url}) # 直接返回一个请求对象即可 # 2. 图片存储路径 def file_path(self, request, response=None, info=None, *, item=None): # 当前获取请求的url的方式有2种 # 获取到当前的url 用于处理下载图片的名称 file_name = item['img_src'].split("/")[-1] # 用item拿到url # file_name = request.meta['url'].split("/")[-1] # 用meta传参获取 return file_name # 3. 可能需要对item进行更新 def item_completed(self, results, item, info): # print('results', results) for r in results: # 获取每个图片的路径 print(r[1]['path']) return item # 一定要return item 把数据传递给下一个管道
接着我们再定义一个保存数据的函数,并设置好存储的文件名,然后存储的路径需要在设置中(setting)文件中,添加IMAGE_STORE设置好存储的路径
ITEM_PIPELINES = {
"desk.pipelines.DeskPipeline": 300,
"desk.pipelines.ImgPipeline": 400, # 图片下载管道
}
# 配置存储图片的路径
IMG_STORE = './imgs'
1.保存图片需要导入ImagesPipeline类
2.需要配置settings.py 开启管道 并设置保存路径
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。