python爬虫之Scrapy框架,基本介绍使用以及用框架下载图片案例( 四 )


from scrapy.pipelines.images import ImagesPipelinefrom scrapy.exceptions import DropItemfrom scrapy import Requestclass ScrapydemmoPipeline:def process_item(self, item, spider):return itemclass ImageDownloadPipeline(ImagesPipeline):def get_media_requests(self, item, info):# 下载图片,如果传过来的是集合需要循环下载# meta里面的数据是从spider获取,然后通过meta传递给下面方法:file_pathyield Request(url = item['image_url'],meta = {'filename':item['image_name']})def item_completed(self, results, item, info):# 分析下载结果并剔除下载失败的图片image_paths = [x['path'] for ok, x in results if ok]if not image_paths:raise DropItem("Item contains no images")return itemdef file_path(self, request, response=None, info=None):# 接收上面meta传递过来的图片名称file_name = request.meta['filename']return file_name

  • get_media_requests() 。它的第一个参数 item 是爬取生成的 Item 对象 。我们将它的 url 字段取出来,然后直接生成 Request 对象 。此 Request 加入调度队列,等待被调度,执行下载 。
  • item_completed(),它是当单个 Item 完成下载时的处理方法 。因为可能有个别图片未成功下载,所以需要分析下载结果并剔除下载失败的图片 。该方法的第一个参数 results 就是该 Item 对应的下载结果,它是一个列表形式,列表每一个元素是一个元组,其中包含了下载成功或失败的信息 。这里我们遍历下载结果找出所有成功的下载列表 。如果列表为空,那么说明该 Item 对应的图片下载失败了,随即抛出异常DropItem,该 Item 忽略 。否则返回该 Item,说明此 Item 有效 。
以上两个函数即可下载图片了,图片名称为自动已哈希值命名,如:
0db6e07054d966513f0a6f315b687f205c7ced90.jpg 这种命名方式不友好,所以我们需要重写 file_path函数,自定义图片名称 。
  • file_path():它的第一个参数 request 就是当前下载对应的 Request 对象 。这个方法用来返回保存的文件名,接收上面meta传递过来的图片名称,将图片以原来的名称和定义格式进行保存 。
5、编写执行文件run.py运行
在项目下新建run.py作为执行文件
from scrapy import cmdline#cmdline.execute('scrapy crawl image_download --nolog'.split())cmdline.execute('scrapy crawl image_download'.split())运行此文件,执行结果,在目录下载第一页壁纸完成 。
python爬虫之Scrapy框架,基本介绍使用以及用框架下载图片案例

文章插图
 
六、小结除了 ImagesPipeline 处理图片外,还有 FilesPipeline 可以处理文件,使用方法与图片类似,事实上 ImagesPipeline 是 FilesPipeline 的子类,因为图片也是文件的一种 。
Scrapy很强大,对于大型网站非常实用,还可以同时运行多个爬虫程序,提升效率 。Scrapy还有很多功能,可以自己研究 。




推荐阅读