理解Scrapy中的回调

时间:2014-03-25 23:27:36

标签: python callback scrapy

我是Python和Scrapy的新手。我之前没有使用过回调函数。但是,我现在为下面的代码做。将执行第一个请求,并将其响应发送到定义为第二个参数的回调函数:

def parse_page1(self, response):
    item = MyItem()
    item['main_url'] = response.url
    request = 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

我无法理解以下事项:

  1. item如何填充?
  2. request.meta行是否在response.meta的{​​{1}}行之前执行?
  3. parse_page2返回item的位置在哪里?
  4. parse_page2return request语句的需求是什么?我认为提取的物品需要从这里返回。

3 个答案:

答案 0 :(得分:16)

阅读docs

  

对于蜘蛛,刮擦周期会经历这样的事情:

     
      
  1. 首先生成初始请求以抓取第一个URL,然后指定要使用响应调用的回调函数   从这些请求下载。

         

    首先要求执行的请求是通过调用   start_requests()方法(默认情况下)生成Request   start_urlsparse方法中指定的网址作为回调   请求的功能。

  2.   
  3. 在回调函数中,您解析响应(网页)并返回Item个对象,Request个对象或两者的可迭代对象。   那些请求也将包含一个回调(可能是相同的)和将   然后由Scrapy下载,然后由他们处理他们的响应   指定的回调。

  4.   
  5. 在回调函数中,您通常使用选择器来解析页面内容(但您也可以使用BeautifulSoup,lxml或其他   您喜欢的机制)并使用已解析的数据生成项目。

  6.   
  7. 最后,从蜘蛛返回的项目通常会持久保存到数据库(在某些项目管道中)或写入文件   使用 Feed导出

  8.   

数目:

  

'item' request.meta行之前,response.meta行执行parse_page2行的效果如何?

蜘蛛由Scrapy引擎管理。它首先从start_urls中指定的URL发出请求,然后将其传递给下载程序。下载完成后,将调用请求中指定的回调。如果回调返回另一个请求,则重复相同的操作。如果回调返回Item,则该项目将传递给管道以保存已删除的数据。

  

parse_page2返回的项目在哪里?

     

return requestparse_page1声明的需要是什么?我认为提取的物品需要从这里返回?

正如文档中所述,每个回调(parse_page1parse_page2)都可以返回RequestItem(或其中的可迭代)。 parse_page1会返回Request而不是Item,因为需要从其他网址中删除其他信息。第二个回调parse_page2返回一个项目,因为所有信息都已被删除并准备好传递给管道。

答案 1 :(得分:1)

  1. 是的,scrapy使用a twisted reactor来调用spider函数,因此使用单个循环和单个线程确保
  2. spider函数调用者期望获得item / s或request / s作为回报,请求被放入队列以供将来处理,并且项目被发送到配置的管道
  3. 在请求meta中保存项目(或任何其他数据)只有在获得响应时需要进一步处理才有意义,否则显然最好从parse_page1返回它并避免额外的http请求电话

答案 2 :(得分:1)

scrapy: understanding how do items and requests work between callbacks中的

,eLRuLL的答案很棒。

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

在scrapy.doc给出的代码中,它不会声明page1和的url和请求。我们将page1的网址设置为" http://www.example.com.html"。

[parse_page1]是

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

[parse_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

当下载page1的响应时,调用parse_page1来生成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 recording  urls of page1 and page2.

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

@Html.TextBox(property.Name, "2017/08/24T09:31:00", new {@type="datetime-local", @step="1", @class="form-control"});
@Html.ValidationMessage(property.Name, "", new { @class = "text-danger" })