2016-03-05 162 views
3

我想刮刮擦框架。一些請求被重定向,但start_requests中設置的回調函數沒有爲這些重定向的url請求調用,但對非重定向url請求正常工作。回調重定向的請求Scrapy

我在start_requests功能如下代碼:

for user in users: 
    yield scrapy.Request(url=userBaseUrl+str(user['userId']),cookies=cookies,headers=headers,dont_filter=True,callback=self.parse_p) 

但這self.parse_p被稱爲只對非302的請求。

回答

4

我想你會得到最後一頁的回調(在重定向之後)。重定向已被RedirectMiddleware照顧。您可以禁用它,然後您將不得不手動執行所有重定向。如果你想有選擇地關閉了幾個類型的請求重定向你可以做這樣的:

request = scrapy.Request(url, meta={'dont_redirect': True} callback=self.manual_handle_of_redirects) 

我不知道的是,中間請求/響應是非常有趣的,雖然。這也是RedirectMiddleware認爲的。因此,它自動執行重定向並將中間URL(唯一有趣的事情)保存在:

response.request.meta.get('redirect_urls') 

您有幾個選項!

例蜘蛛:

import scrapy 

class DimSpider(scrapy.Spider): 
    name = "dim" 

    start_urls = (
     'http://example.com/', 
    ) 

    def parse(self, response): 
     yield scrapy.Request(url="http://example.com/redirect302.php", dont_filter=True, callback=self.parse_p) 

    def parse_p(self, response): 
     print response.request.meta.get('redirect_urls') 
     print "done!" 

示例輸出...

DEBUG: Crawled (200) <GET http://www.example.com/> (referer: None) 
DEBUG: Redirecting (302) to <GET http://myredirect.com> from <GET http://example.com/redirect302.php> 
DEBUG: Crawled (200) <GET http://myredirect.com/> (referer: http://example.com/redirect302.com/) 
['http://example.com/redirect302.php'] 
done! 

如果你真的要刮302頁,你必須explicitcly允許它。例如這裏,我允許302並設置dont_redirectTrue

handle_httpstatus_list = [302] 
def parse(self, response): 
    r = scrapy.Request(url="http://example.com/redirect302.php", dont_filter=True, callback=self.parse_p) 
    r.meta['dont_redirect'] = True 
    yield r 

最終的結果是:

DEBUG: Crawled (200) <GET http://www.example.com/> (referer: None) 
DEBUG: Crawled (302) <GET http://example.com/redirect302.com/> (referer: http://www.example.com/) 
None 
done! 

這種蜘蛛應該手動跟蹤302個網址:

import scrapy 

class DimSpider(scrapy.Spider): 
    name = "dim" 

    handle_httpstatus_list = [302] 

    def start_requests(self): 
     yield scrapy.Request("http://page_with_or_without_redirect.html", 
          callback=self.parse200_or_302, meta={'dont_redirect':True}) 

    def parse200_or_302(self, response): 
     print "I'm on: %s with status %d" % (response.url, response.status) 
     if 'location' in response.headers: 
      print "redirecting" 
      return [scrapy.Request(response.headers['Location'], 
            callback=self.parse200_or_302, meta={'dont_redirect':True})] 

要小心。不要忽略設置handle_httpstatus_list = [302]否則你會得到「HTTP狀態碼不處理或不允許」。

+0

我已經編輯了代碼和調用回調的問題。您所描述的行爲不適用於在302代碼之後重定向的請求。 –

+0

另外,我想這個框架的更好的方法是。該代碼不會抓取重定向的網址。 –

+0

已更新,其中包含更新問題中的一些內容。我還會爲'dont_redirect'' meta添加一個案例(雖然可能不那麼有趣) – neverlastn

0

默認情況下,scrapy沒有遵循302重定向。

在你的蜘蛛,你可以使用custom_settings屬性:

custom_settings 的,將自該項目範圍內的配置運行此蜘蛛時,可以覆蓋設置的字典。它必須被定義爲類屬性,因爲設置在實例化之前被更新。

組的URL請求可以被重定向的重定向數量如下:

class MySpider(scrapy.Spider): 
    name = "myspider" 
    allowed_domains = ["example.com"] 
    start_urls = [ "http://www.example.com" ] 

    custom_settings = { 'REDIRECT_MAX_TIMES': 333 } 

    def start_requests(self): 
     # Your code here 

我設置333作爲一個例子的限制。

我希望這會有所幫助。