2014-03-25 39 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.