Scrapy无法达到Request的回调

时间:2015-10-27 06:44:15

标签: python scrapy

我在蜘蛛中使用下一个代码:

def parse_item(self, response):
    item = MyItem()
    item['price'] = [i for i in self.get_usd_price(response)]
    return item

def get_usd_price(self, response):
    yield FormRequest(
        'url',
        formdata={'key': 'value'},
        callback=self.get_currency
    )

def get_currency(self, response):
    self.log('lalalalala')

问题是我无法达到我的get_currency回调。在我的记录器中,我看到price项的值为[<POST url>]。我究竟做错了什么?我尝试将dont_filter添加到FormRequest,将FormRequest更改为simple get Request

更新

我也尝试了GHajba的建议(到目前为止没有成功):

def parse_item(self, response):
    item = MyItem()
    self.get_usd_price(response, item)
    return item

def get_usd_price(self, response, item):
    request = FormRequest(
        'url',
        formdata={'key': 'value'},
        callback=self.get_currency
    )
    request.meta['item'] = item
    yield request

def get_currency(self, response):
    self.log('lalalalala')
    item = response.meta['item']
    item['price'] = 123
    return item

2 个答案:

答案 0 :(得分:1)

您的问题是您将get_usd_price中创建的生成器的值分配给您的项目。您可以通过更改方法以及如何调用它来解决此问题。

您必须yield FormRequest,但您不能使用此值来对Scrapy产生影响。只需调用函数get_usd_price,而无需将其分配给item['price']

self.get_usd_price(response, item)

您必须为您的函数提供item,因为Scrapy是异步的,因此您无法确定FormRequest何时正在执行。现在,您必须将item作为meta的{​​{1}}参数传递,然后您可以访问FormRequest函数中的项目和get_currency项目那里。

您可以在文档中详细了解yieldhttp://doc.scrapy.org/en/latest/topics/request-response.html#scrapy.http.Request.meta

答案 1 :(得分:1)

这不是scrapy如何工作,你只能在每个方法上产生一个请求或一个项目,但你不能以这种方式产生响应,如果你想更新项目的价格信息然后产生你应该做的事情如下:

def parse_item(self, response):
    item = MyItem()
    # populate the item with this response data
    yield FormRequest(
        'url',
        formdata={'key': 'value'},
        callback=self.get_currency, meta={'item':item}
    )

def get_currency(self, response):
    self.log('lalalalala')
    item = response.meta['item']
    item['price'] = 123 # get your price from the response body.
    # keep populating the item with this response data
    yield item

因此,请检查在请求之间传递信息,您需要使用元参数。