本文已参与「新人创作礼」活动,一起开启掘金创作之路。
一、前言
上一篇,初步介绍了Scrapy框架的使用,具体可以看:【Python爬虫Scrapy框架】一、Scrapy爬虫框架的入门案例 在pipeline,我们可以处理提取的数据。之前为了方便,我选择直接打印。 这篇来讲一下如何下载保存上一篇中的图片。
二、Image Pipeline
官方文档如下:doc.scrapy.org/en/latest/t…
Scrapy提供了专门处理下载的Pipeline,包括文件下载和图片下载。下载文件和图片的原理与抓取页面的原理一样,因此下载支持异步和多线程,下载十分高效。
使用如下:
1、修改settings文件
在settings.py文件的最后添加代码,设置图片存储路径。(根据自己的需要自行修改,这里将路径定义为当前路径下的images子文件夹)
IMAGES_STORE='./images/'
2、认识三个函数
- get_media_requests() 它的第一个参数item是爬取生成的Item对象。我们将它的url字段取出来,然后直接生成Request对象。此Request加入到调度队列,等待被调度,执行下载。
- file_path() 它的第一个参数request就是当前下载对应的Request对象。这个方法用来返回保存的文件名。
- item_completed() 它是当单个Item完成下载时的处理方法。因此并不是每张图片都会下载成功,所以我们需要分析下载结果并去除掉下载失败的图片。该方法的第一个参数results就是该item对应的下载结果。它是一个列表形式,列表的每一个元素就是一个元组,其中包含了下载成功或失败的信息。如果我们遍历下载结果找出所有成功的下载列表。如果列表为空那么该Item对应的图片下载失败,随即抛出异常DropItem,就将该item忽略。
3、编写pipeline.py文件
其它几个py文件与上一篇相同。
from scrapy.pipelines.images import ImagesPipeline
from scrapy.exceptions import DropItem
import scrapy
# 项目管道FirstproPipeline(需要改成自己的)
class FirstproPipeline(ImagesPipeline):
def get_media_requests(self, item, info):
image_url = 'https://pic.netbian.com/' + item['link'] # 构建需要下载图片的url
yield scrapy.Request(image_url, meta={'name': item['name']}) # 构建下载图片的名称
def file_path(self, request, response=None, info=None, *, item=None):
name = request.meta['name'] # 接收上面保存的名称
filename = name + '.jpg' # 给图片添加后缀
return filename
def item_completed(self, results, item, info):
image_paths = [x['path'] for ok, x in results if ok]
if not image_paths:
raise DropItem('Image Download failed')
return item
4、运行结果
下载了3页,但文件夹中仅有57张图片。
我感到匪夷所思呀,于是我一张一张地将本地图片与网站中的图片进行比对,发现有四张图片是重名的,下载时覆盖了三张,从而验证没有漏下载!!!!可放心食用。
三、推荐阅读
四、未来可期
文章到这里就要结束了,但故事还没有结局
如果本文对你有帮助,记得点个赞👍哟,也是对作者最大的鼓励🙇♂️。
如有不足之处可以在评论区👇多多指正,我会在看到的第一时间进行修正
作者:爱打瞌睡的CV君 CSDN:blog.csdn.net/qq_44921056 本文仅用于交流学习,未经作者允许,禁止转载,更勿做其他用途,违者必究。