Scrapy自带的FilesPipeline和ImagesPipeline,下载图片和文件非常方便。根据其官方文档[1],我们可以很方便的打开这两条Pipeline。如果只是想下载图片,可以同时使用FilesPipeline和ImagesPipeline,毕竟图片也是文件。但是由于ImagesPipeline的使用需要单独安装第三方库Pillow,所以我们以FilesPipeline为例进行说明。假设爬虫通过解析网页源代码得到一张图片。图片地址为:https://kingname-1257411235.cos.ap-chengdu.myqcloud.com/640.gif当然,png、jpg,甚至rar、pdf、zip都可以。为了使用Scrapy自带的FilesPipeline下载这个图片,我们需要做几个步骤来设置它。定义项目首先定义任何项目。您需要确保项目必须包含file_urls字段和files字段。除了这两个必填字段外,您还可以任意添加其他字段。启动FilesPipeline在settings.py中,找到ITEM_PIPELINES配置,如果有注释,取消注释。然后添加如下配置:'scrapy.pipelines.files.FilesPipeline':1添加一个配置项FILES_STORE,其值为要保存图片的文件夹地址。修改后如下图所示:下载图片接下来进入我们具体的爬虫逻辑。在爬虫中,当你在任意一个parse函数中提取出一张或几张图片的url后,将它们(它们)以列表的形式放入item中的file_urls字段中。如下所示。请注意,文件字段此时不需要设置任何值。其他非必填字段只能根据您的需要设置。得到结果由于我们将scrapy.pipelines.images.FilesPipeline的优先级设置为1,即最高优先级,它会先于所有其他Pipelines运行。因此,我们稍后可以在其他管道中查看item的files字段,会发现我们需要的图片地址已经在里面了。如下图所示:item中的files字段变成了一个包含字典的列表。字典里有一个key叫path,它的值就是图片在电脑上的路径。例如full/7f471f6dbc08c2db39125b20b0471c3b21c58f3e.gif表示images文件夹中full文件夹中的7f471f6dbc08c2db39125b20b0471c3b21c58f3e.gif文件的名称,如下图:为文件的md5值。如果要重命名,可以在后续管道中根据path的值找到文件,然后修改名称。修改请求头看到这里,你是不是有疑问了?使用FilesPipeline时,Scrapy会添加请求头吗?它将使用哪个请求标头?事实上,Scrapy在使用FilesPipeline和ImagesPipeline时,是不会设置请求头的。如果网站监听请求图片或文件的请求头,可以立即发现请求是通过Scrapy发起的。为了证明这一点,我们可以看一下FilesPipeline的源码:在scrapy/pipelines/files.py文件中,我们可以看到FilesPipeline通过get_media_requests方法构造了一个图片请求对象。此请求对象未设置任何请求标头。上面的截图是旧版本Scrapy的源代码。在新版本的源代码中,get_media_requests可能看起来像这样:另外对于requestheader,我们可以自己写一个pipeline,继承FilesPipeline但是重写get_media_requests方法,如下图所示:注意在实际使用中可能还需要添加Host和Referer。然后修改settings.py中的ITEM_PIPELINES指向我们自定义的管道:这样FilesPipeline就可以正确添加请求头了。最后,我要问你一个问题。FilesPipeline发起的请求会不会经过downloader中间件?想添加代理IP怎么办?欢迎在本文下方评论回复。参考[1]官方文档:https://docs.scrapy.org/en/latest/topics/media-pipeline.html#using-the-files-pipeline本文转载自微信公众号《未闻之代码》,您可以通过以下二维码关注。转载本文请联系Code公众号。
