在scrapy的start_requests()中返回项目

时间:2016-02-09 18:57:41

标签: python scrapy

我正在编写一个scrapy蜘蛛,它将许多网址作为输入并将其分类为类别(作为项目返回)。这些网址通过我的抓取工具start_requests()方法提供给蜘蛛。

有些网址可以在不下载的情况下对其进行分类,因此我希望yield直接Itemstart_requests()中的Response,这是scrapy禁止的。我怎么能绕过这个?

我考虑过在自定义中间件中捕获这些请求会将它们变成虚假的Item对象,然后我可以在请求回调中将其转换为using value_type = xpair<const key_type, mapped_type>; 个对象,但任何更干净的解决方案都是欢迎。

2 个答案:

答案 0 :(得分:2)

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

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 方法中,只需检查 direct_return_url 中的键 response.meta。如果是,只需生成一个项目并将 response.url 放入其中,然后生成该项目。

答案 1 :(得分:1)

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

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

  • 对于不需要请求的特殊网址,您可以
    • 直接调用您的管道的process_item(),不要忘记导入管道并从您的网址创建scrapy.item
    • 正如您所提到的,在请求中将url作为meta传递,并且具有单独的解析函数,该函数只返回url
  • 对于所有剩余的网址,您可以启动“正常”请求,因为您可能已经定义了