【问题标题】:Returning Items in scrapy's start_requests()在 scrapy 的 start_requests() 中返回项目
【发布时间】:2016-02-09 18:57:41
【问题描述】:

我正在编写一个scrapy spider,它将许多网址作为输入并将它们分类(作为项目返回)。这些 URL 是通过我的爬虫的 start_requests() 方法提供给蜘蛛的。

有些网址不用下载就可以分类,所以我想在start_requests()中直接给他们yield一个Item,这是scrapy禁止的。我该如何规避呢?

我曾考虑在自定义中间件中捕获这些请求,将它们变成虚假的 Response 对象,然后我可以在请求回调中将其转换为 Item 对象,但欢迎使用任何更简洁的解决方案。

【问题讨论】:

    标签: python scrapy


    【解决方案1】:

    您可以使用下载器中间件来完成这项工作。

    start_requests() 中,您应该始终提出请求,例如:

    def start_requests(self):
        for url in all_urls:
            yield scrapy.Request(url)
    

    但是,你应该编写一个下载器中间件:

    class DirectReturn:
        def process_request(self, request, spider):
            image_url = request.url
            if url in direct_return_url_set:
                resp = Response(image_url, request=request)
                request.meta['direct_return_url': True]
                return resp
            else:
                return request
    

    然后,在您的 parse 方法中,只需检查 response.meta 中的键 direct_return_url。如果是,只需生成一个项目并将 response.url 放入其中,然后生成该项目。

    【讨论】:

      【解决方案2】:

      我认为使用蜘蛛中间件并覆盖 start_requests() 将是一个好的开始。

      在你的中间件中,你应该遍历 start_urls 中的所有 url,并且可以使用条件语句来处理不同类型的 url。

      • 对于不需要请求的特殊 URL,您可以
        • 直接调用你的pipeline的process_item(),不要忘记导入你的pipeline并为此从你的url创建一个scrapy.item
        • 正如您所提到的,将 url 作为元数据传递到请求中,并有一个单独的解析函数,它只会返回 url
      • 对于所有剩余的 URL,您可以启动“正常”请求,因为您可能已经定义了

      【讨论】:

      • 谢谢!我不知道可以从中间件访问管道,这可能是最好的解决方案。
      • 感谢您的回答。我必须调用哪个管道?如果我没有用户定义的管道,那是“默认管道”?谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多