在构造Scrapy Request对象时,我可以指定任何方法作为回调吗?

时间:2014-12-23 00:54:15

标签: python callback web-scraping scrapy scrapy-spider

我正在尝试创建一个请求,并且之前已经在我的蜘蛛类中传递一个函数作为回调。但是,我已经将该函数移动到Item子类,因为我想要有不同类型的Items,并且每种类型的项目的回调可能不同(例如,如果我将要提升DropItem的那一刻)内容类型不是预期的,并且每种类型的Item都有一组不同的有效MIME类型。所以,我想知道的是我可以从我的Item子类传递一个函数作为回调参数吗?基本上是这样的:

item = MyCustomItem()  # Extends scrapy.item.Item
# bunch of code here...
req = Request(urlparse.urljoin(response.url, url), method="HEAD", callback=item.parse_resource_metadata)

目前item.parse_resource_metadata未被调用。打印req.callback给出了

<bound method ZipResource.parse_resource_metadata of {(correct data for this Item object}>

因此它至少构建了我所希望的请求。

[编辑] Mea culpa,没有调用回调,因为起始页面没有被抓取(我不得不重写parse_start_url()。但事实证明我做错了,我问的好事!

1 个答案:

答案 0 :(得分:3)

理论上,它是可行的,因为callback只是一个可调用response作为它的参数。

虽然Item只是字段的容器,但它们用于存储数据,不应该将逻辑放在那里

最好在蜘蛛中创建一个方法pass the item instance inside meta

def parse(self, response):
    ...
    item = MyCustomItem()
    ...
    yield Request(urlparse.urljoin(response.url, url), 
                  method="HEAD", 
                  meta={'item': item},
                  callback=self.my_callback)

def my_callback(self, response):
    item = response.meta['item']
    ...

我不完全确定您要实现的目标,但您也可以仔细查看Item LoadersInput and Output Processors