多步/嵌套scrapy文件下载

时间:2018-03-23 13:39:10

标签: python web-scraping scrapy web-crawler

我尝试使用自定义scrapy管道下载文件。但是文件url并不容易获得。以下是步骤:

  • 管道获取包含pdfLink属性
  • 的项目
  • pdfLink的页面是pdf的包装,嵌入在iframe中

然后我扩展了FilesPipeline类:

import scrapy
from scrapy.pipelines.files import FilesPipeline

class PdfPipeline(FilesPipeline):
    def get_media_requests(self, item, spider):
        yield scrapy.Request(item['pdfLink'],
            callback=self.get_pdfurl)



    def get_pdfurl(self, response):
        import logging
        logging.info('...............')
        print response.url
        yield scrapy.Request(response.css('iframe::attr(src)').extract()[0])

但是:

  1. 下载的文件是pdfLink指出的网页,而不是嵌入的pdf文件。
  2. 日志中未显示printlogging.info
  3. 然后似乎没有回调get_pdfurl。难道我做错了什么 ?如何下载这样的嵌套文件?

1 个答案:

答案 0 :(得分:0)

通过使用两个连续的管道找到解决方案,其中第一个是Item pipeline - Take screenshot of item中构建的。

class PdfWrapperPipeline(object):
    def process_item(self, item, spider):
        wrapper_url = self.WRAPPER_URL.format(item.get('pdfLink'))
        request = scrapy.Request(item.get('pdfLink'))
        dfd = spider.crawler.engine.download(request, spider)
        dfd.addBoth(self.return_item, item)
        return dfd

    def return_item(self, response, item):
        if response.status != 200:
            # Error happened, return item.
            return item

        url = response.css('iframe::attr(src)').extract()[0]
        item['pdfUrl'] = url
        return item

class PdfPipeline(FilesPipeline):
    def get_media_requests(self, item, spider):
        yield scrapy.Request(item.get('pdfUrl'))

然后在settings.py中设置高于pdf管道优先级的包装器管道优先级。

ITEM_PIPELINES = {
    'project.pipelines.PdfWrapperPipeline': 1,
    'project.pipelines.PdfPipeline': 2,
} 

响应已首先发布在scrapy's github