scrapy:了解回调之间的项目和请求如何工作

时间:2015-11-07 23:44:26

标签: python scrapy

我正在与Scrapy斗争,我不明白回调之间的确切传递方式是如何运作的。也许有人可以帮助我。

我正在调查http://doc.scrapy.org/en/latest/topics/request-response.html#passing-additional-data-to-callback-functions

def parse_page1(self, response):
    item = MyItem()
    item['main_url'] = response.url
    request = scrapy.Request("http://www.example.com/some_page.html",
                             callback=self.parse_page2)
    request.meta['item'] = item
    return request

def parse_page2(self, response):
    item = response.meta['item']
    item['other_url'] = response.url
    return item

我试图一步一步地了解那里的行动:

[parse_page1]

  1. item = MyItem()< - 对象项已创建
  2. item['main_url'] = response.url< - 我们正在为对象项目
  3. 的main_url分配值
  4. request = scrapy.Request("http://www.example.com/some_page.html", callback=self.parse_page2)< - 我们正在请求新页面并启动parse_page2以废弃它。
  5. [parse_page2]

    1. item = response.meta['item']< - 我在这里不明白。我们正在创建一个新的对象项,或者这是在[parse_page1]中创建的对象项?什么response.meta [' item']的意思是什么?我们只传递3个请求,例如链接和回调,我们没有添加任何我们可以参考的其他参数...
    2. item['other_url'] = response.url< - 我们正在为对象项
    3. 的other_url赋值
    4. return item< - 作为请求的结果我们返回项目对象
    5. [parse_page1]

      1. request.meta['item'] = item< - 我们正在分配要求的对象项目?但请求完成后,回调已经返回6 ????
      2. 中的项目
      3. return request< - 我们正在收到请求的结果,所以来自6的项目,我是对的吗?
      4. 我查看了有关scrapy和request / response / meta的所有文档,但我仍然不了解第4点和第7点中发生的情况。

2 个答案:

答案 0 :(得分:4)

line 4: request = scrapy.Request("http://www.example.com/some_page.html",
                         callback=self.parse_page2)
line 5: request.meta['item'] = item
line 6: return request

您对以前的代码感到困惑,让我解释一下(我在此列举了解释):

  1. 在第4行中,您要实例化一个scrapy.Request对象,这不像其他其他请求库一样工作,这里您没有调用url,也没有进入回调函数爱好。

  2. 您要在第5行向scrapy.Request对象添加参数,例如,您还可以声明scrapy.Request对象,如:

    request = scrapy.Request("http://www.example.com/some_page.html", 
            callback=self.parse_page2, meta={'item': item})`
    

    你可以避免第5行。

  3. 当你调用scrapy.Request对象时,在第6行,当scrapy正在使它工作时,比如调用指定的url,转到下面的回调,并传递{{ 1}}如果您按照这样调用请求,那么您也可以避免使用第6行(和第5行):

    meta
  4. 所以这里的想法是你的回调方法应该return scrapy.Request("http://www.example.com/some_page.html", callback=self.parse_page2, meta={'item': item})` (最好是returnyieldRequest,scrapy会输出Item和继续抓取Item

答案 1 :(得分:0)

@ eLRuLL的答案很精彩。我想添加项目转换的一部分。首先,我们将清楚回调函数只有在此请求的响应被重载之后才会起作用。

在scrapy.doc给出的代码中,它没有声明page1和url的请求。我们将page1的url设置为“http://www.example.com.html”。

[parse_page1]是

的回调
scrapy.Request("http://www.example.com.html",callback=parse_page1)`

[parse_page2]是

的回调
scrapy.Request("http://www.example.com/some_page.html",callback=parse_page2)

当下载page1的响应时,调用parse_page1来生成page2的请求:

item['main_url'] = response.url # send "http://www.example.com.html" to item
request = scrapy.Request("http://www.example.com/some_page.html",
                         callback=self.parse_page2)
request.meta['item'] = item  # store item in request.meta

下载page2的响应后,调用parse_page2来重新启动项目:

item = response.meta['item'] #response.meta is equal to request.meta,so here item['main_url'] ="http://www.example.com.html".

item['other_url'] = response.url # response.url ="http://www.example.com/some_page.html"

return item #finally,we get the item recordind  urls of page1 and page2.