2016-07-15 26 views

回答

4

你的意思scrapy.spiders.Rule是在scrapy.CrawlSpider

最常用的,他們做很多的名字說什麼或充當排序鏈接提取和處理的時間之間的中間件換句話說/下載。

process_links位於鏈接被提取並轉化爲請求之間。這裏有很酷的用例,僅舉幾個常見的例子:

  1. 篩選出一些你不喜歡的鏈接。
  2. 手動進行重定向以避免錯誤的請求。

例如:

def process_links(self, link): 
    for link in links: 
     #1 
     if 'foo' in link.text: 
      continue # skip all links that have "foo" in their text 
     yield link 
     #2 
     link.url = link.url + '/' # fix url to avoid unnecessary redirection 
     yield link 

process_requests坐鎮要求剛發之間,它正在下載之前。它與process_links共享一些用例,但實際上可以做一些其他很酷的東西,例如:

  1. 修改標頭(例如cookies)。
  2. 根據url中的一些關鍵字改變細節,如回調。

例如:

def process_req(self, req): 
    # 1 
    req = req.replace(headers={'Cookie':'foobar'}) 
    return req 
    # 2 
    if 'foo' in req.url: 
     return req.replace(callback=self.parse_foo) 
    elif 'bar' in req.url: 
     return req.replace(callback=self.parse_bar) 
    return req 

你可能不會再經常使用它們,但是這兩個可能是在某些情況下確實很方便和容易的快捷方式。

+0

酷!這很棒。謝謝。這解決了我遇到的問題。我有2個問題,雖然1)在你的process_links代碼中,是不是最後2行冗餘,因爲你有一個返回鏈接之前呢? 2)如果我在process_links中返回None,我得到一個「TypeError:'NoneType'對象不可迭代」。我知道我可以忽略這個錯誤,因爲Scrapy移動到下一個鏈接,但是我能以任何方式解決這個錯誤嗎?我希望如果看到一個NoneType返回,Scrapy會繼續前進。 – Arrow

+0

關於#1 - 我剛剛用它來炫耀兩個例子來節省空間。關於#2 - 在我的結尾有一個錯字,'process_links'函數實際上包含一個鏈接列表,並期望有一些列表作爲返回,我已經調整了我的答案以反映這一點。 – Granitosaurus

+0

@Granitosaurus這真的很有幫助 - 謝謝。我相信你的'process_links()'函數可能會將未來的讀者與'return None'語句混淆。任何機會,你可以用'繼續'來替代它跳過不良鏈接或類似的東西,使其更加準確? – UriCS