2014-03-25 38 views
7

我是Python和Scrapy的新手。我之前没有使用过回调函数。不过,我现在要为下面的代码做。第一个请求将被执行的,这个响应将被发送到定义为第二个参数的回调函数:理解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行是否在parse_page2response.meta行之前执行?
  3. 退回itemparse_page2要去哪里?
  4. return request陈述parse_page1需要什么?我认为提取的物品需要从这里返回。

回答

14

阅读docs

蜘蛛,刮周期经过是这样的:

  1. 您可以通过生成初始请求抓取的第一个网址的开头,并指定将从这些请求下载的响应 调用回调函数。

    执行第一请求被通过调用 start_requests()方法,该方法(默认)生成Requeststart_urls指定的 网址和parse方法回调函数 用于请求获得。

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

  3. 在回调函数,你解析页面内容,通常使用选择器(但你也可以使用BeautifulSoup,你喜欢LXML或任何 机制),并产生与所解析的数据项。

  4. 最后,项目返回从蜘蛛将通常保存到数据库中(在某些项目管道)或书面使用饲料出口文件 。

答案:

'item'如何填充是否request.meta线之前parse_page2response.meta行执行?

蜘蛛由Scrapy引擎管理。它首先通过start_urls中指定的URL发出请求,并将它们传递给下载程序。下载完成时,请求中指定的回调被调用。如果回调返回另一个请求,则重复同样的事情。如果回调返回Item,则将该项目传递给管道以保存刮取的数据。

parse_page2正在退货的产品在哪里?

return request陈述parse_page1需要什么?我认为提取的物品需要从这里退回?

如文档所述,每个回调(二者parse_page1parse_page2)可以返回一个RequestItem(或它们的可迭代)。 parse_page1返回一个Request而不是Item,因为需要从其他URL中提取附加信息。第二个回调parse_page2返回一个项目,因为所有的信息都被抓取并准备传递给管道。

+0

我已经阅读过这个部分了......但是我很困惑,我已经提到过代码如何流动。 – Parag

+0

查看我的更新。基本上与其他词语相同的东西。 – warvariuc

+0

感谢您的解释...现在它是有道理的时候,我再次读完整的东西 – Parag

1
  1. 是,scrapy使用a twisted reactor调用蜘蛛的功能,因此使用单一的环路与单一线程保证
  2. 蜘蛛函数调用方期望要么得到产品/秒或请求/ s的回报,请求被放入队列以供将来处理,并且项目被发送到配置管道
  3. 在请求元中保存项目(或任何其他数据)只有在得到响应时需要进一步处理时才有意义,否则显然更好地简单地从parse_page1返回并避免额外的http请求呼叫
+0

谢谢你的好解释......但我仍然困惑在第三个问题......我想我没有解释清楚。所以,我想问的是,parse_page1中的请求实例返回到哪里?为什么需要返回请求 - 当控制达到此声明时调用回调函数吗?另外,我是否可以按照与此处所做的相同的方式传递项目列表,并从parse_page2返回列表? – Parag

1

in scrapy: understanding how do items and requests work between callbacks ,eLRuLL的回答非常好。

我想添加项目变换的一部分。首先,我们将明确回调函数只有在该请求的响应被重载之前才起作用。

在scrapy.doc给出的代码中,它不声明page1和url的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) 

当第1页的响应被下载回调,parse_page1被调用来生成第2页的请求:

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给retru一个项目:

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. 
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.