請求和響應
Scrapy的Request和Response對象用於耙梳網站。
通常,Request對象在爬蟲程式中產生並傳遞到系統,直到它們到達下載程式,後者執行請求並返回一個Response對象,該對象返回到發出請求的爬蟲程式。
上面一段話比較拗口,有web經驗的同學,應該都瞭解的,不明白看下面的圖大概理解下。
爬蟲->Request:建立Request->Response:擷取下載資料Response->爬蟲:資料
兩個類Request和Response類都有一些子類,它們添加基類中不需要的功能。這些在下面的請求子類和 響應子類中描述。 Request objects
class scrapy.http.Request(url[, callback, method='GET', headers, body, cookies, meta, encoding='utf-8', priority=0, dont_filter=False, errback])
一個Request對象表示一個HTTP請求,它通常是在爬蟲產生,並由下載執行,從而產生Response。
參數: url(string) - 此請求的網址 callback(callable) - 將使用此請求的響應(一旦下載)作為其第一個參數調用的函數。有關更多資訊,請參閱下面的將附加資料傳遞給回呼函數。如果請求沒有指定回調,parse()將使用spider的 方法。請注意,如果在處理期間引發異常,則會調用errback。 method(string) - 此請求的HTTP方法。預設為'GET'。 meta(dict) - 屬性的初始值Request.meta。如果給定,在此參數中傳遞的dict將被淺複製。 body(str或unicode) - 請求體。如果unicode傳遞了a,那麼它被編碼為 str使用傳遞的編碼(預設為utf-8)。如果 body沒有給出,則儲存一個Null 字元串。不管這個參數的類型,儲存的最終值將是一個str(不會是unicode或None)。 headers(dict) - 這個請求的頭。dict值可以是字串(對於單值標題)或列表(對於多值標題)。如果 None作為值傳遞,則不會發送HTTP頭。
cookie(dict或list) - 請求cookie。這些可以以兩種形式發送。 使用dict:
request_with_cookies = Request(url="http://www.example.com", cookies={'currency': 'USD', 'country': 'UY'})
* 使用列表: ``` request_with_cookies = Request(url="http://www.example.com", cookies=[{'name': 'currency', 'value': 'USD', 'domain': 'example.com', 'path': '/currency'}]) ```
後一種形式允許定製 cookie的屬性domain和path屬性。這隻有在儲存Cookie用於以後的請求時才有用。
當某些網站返回Cookie(在響應中)時,這些Cookie會儲存在該域的Cookie中,並在將來的請求中再次發送。這是任何常規網路瀏覽器的典型行為。但是,如果由於某種原因,您想要避免與現有Cookie合并,您可以通過將dont_merge_cookies關鍵字設定為True 來指示Scrapy如此操作 Request.meta。
不合并Cookie的請求樣本:
request_with_cookies = Request(url="http://www.example.com", cookies={'currency': 'USD', 'country': 'UY'}, meta={'dont_merge_cookies': True})
有關詳細資料,請參閱CookiesMiddleware。 encoding(string) - 此請求的編碼(預設為'utf-8')。此編碼將用於對URL進行百分比編碼,並將本文轉換為str(如果給定unicode)。 priority(int) - 此請求的優先順序(預設為0)。調度器使用優先順序來定義用於處理請求的順序。具有較高優先順序值的請求將較早執行。允許負值以指示相對低優先順序。 dont_filter(boolean) - 表示此請求不應由發送器過濾。當您想要多次執行相同的請求時忽略重複過濾器時使用。小心使用它,或者你會進入爬行迴圈。預設為False。
errback(callable) - 如果在處理請求時引發任何異常,將調用的函數。這包括失敗的404 HTTP錯誤等頁面。它接收一個Twisted Failure執行個體作為第一個參數。有關更多資訊,請參閱使用errbacks在請求處理中捕獲異常。
url
包含此請求的網址的字串。請記住,此屬性包含轉義的網址,因此它可能與建構函式中傳遞的網址不同。
此屬性為唯讀。變更要求使用的URL replace()。
method
表示請求中的HTTP方法的字串。這保證是大寫的。例如:"GET","POST","PUT"等
headers
包含請求標題的類似字典的對象。
body
包含請求本文的str。
此屬性為唯讀。變更要求使用的本文 replace()。 meta
包含此請求的任意中繼資料的字典。此dict對於新請求為空白,通常由不同的Scrapy組件(擴充程式,中介軟體等)填充。因此,此dict中包含的資料取決於您啟用的擴充。
有關Scrapy識別的特殊元鍵列表,請參閱Request.meta特殊鍵。
當使用or 方法複製請求時,此dict是淺複製的 ,並且也可以在您的爬蟲中從屬性訪問。copy()replace()response.meta
copy()
返回一個新的請求,它是這個請求的副本。另請參見: 將附加資料傳遞到回呼函數。
replace([url, method, headers, body, cookies, meta, encoding, dont_filter, callback, errback])
返回具有相同成員的Request對象,但通過指定的任何關鍵字參數賦予新值的成員除外。該屬性Request.meta是預設複製(除非新的值在給定的meta參數)。另請參見 將附加資料傳遞給回呼函數。 將附加資料傳遞給回呼函數
請求的回調是當下載該請求的響應時將被調用的函數。將使用下載的Response對象作為其第一個參數來調用回呼函數。
例:
def parse_page1(self, response): return scrapy.Request("http://www.example.com/some_page.html", callback=self.parse_page2)def parse_page2(self, response): # this would log http://www.example.com/some_page.html self.logger.info("Visited %s", response.url)
在某些情況下,您可能有興趣向這些回呼函數傳遞參數,以便稍後在第二個回調中接收參數。您可以使用該Request.meta屬性。
以下是使用此機制傳遞項目以填充來自不同頁面的不同欄位的樣本:
def parse_page1(self, response): item = MyItem() item['main_url'] = response.url request = scrapy.Request("http://www.example.com/some_page.html", callback=self.parse_page2) request.meta['item'] = item yield requestdef parse_page2(self, response): item = response.meta['item'] item['other_url'] = response.url yield item 使用errbacks在請求處理中捕獲異常
請求的errback是在處理異常時被調用的函數。
它接收一個Twisted Failure執行個體作為第一個參數,並可用於跟蹤串連建立逾時,DNS錯誤等。
這裡有一個樣本爬蟲記錄所有錯誤,並捕獲一些特定的錯誤,如果需要:
import scrapyfrom scrapy.spidermiddlewares.httperror import HttpErrorfrom twisted.internet.error import DNSLookupErrorfrom twisted.internet.error import TimeoutError, TCPTimedOutErrorclass ErrbackSpider(scrapy.Spider): name = "errback_example" start_urls = [ "http://www.httpbin.org/", # HTTP 200 expected "http://www.httpbin.org/status/404", # Not found error "http://www.httpbin.org/status/500", # server issue "http://www.httpbin.org:12345/", # non-responding host, timeout expected "http://www.httphttpbinbin.org/", # DNS error expected ] def start_requests(self): for u in self.start_urls: yield scrapy.Request(u, callback=self.parse_httpbin, errback=self.errback_httpbin, dont_filter=True) def parse_httpbin(self, response): self.logger.info('Got successful response from {}'.format(response.url)) # do something useful here... def errback_httpbin(self, failure): # log all failures self.logger.error(repr(failure)) # in case you want to do something special for some errors, # you may need the failure's type: if failure.check(HttpError): # these exceptions come from HttpError spider middleware # you can get the non-200 response response = failure.value.response self.logger.error('HttpError on %s', response.url) elif failure.check(DNSLookupError): # this is the original request request = failure.request self.logger.error('DNSLookupError on %s', request.url) elif failure.check(TimeoutError, TCPTimedOutError): request = failure.request self.logger.error('TimeoutError on %s', request.url) Request.meta特殊鍵
該Request.meta屬性可以包含任何任意資料,但有一些特殊的鍵由Scrapy及其內建擴充識別。
那些是:
dont_redirectdont_retryhandle_httpstatus_listhandle_httpstatus_alldont_merge_cookies(參見cookies建構函式的Request參數)cookiejardont_cacheredirect_urlsbindaddressdont_obey_robotstxtdownload_timeoutdownload_maxsizedownload_latencyproxy
bindaddress
用於執行請求的出站IP地址的IP。 download_timeout
下載器在逾時前等待的時間量(以秒為單位)。參見:DOWNLOAD_TIMEOUT。 download_latency
自請求已啟動以來,用於擷取響應的時間量,即通過網路發送的HTTP訊息。此元鍵僅在響應已下載時可用。雖然大多數其他元鍵用於控制Scrapy行為,但這應該是唯讀。 請求子類
這裡是內建子類的Request列表。您還可以將其子類化以實現您自己的自訂功能。
FormRequest對象
FormRequest類擴充了Request具有處理HTML表單的功能的基礎。它使用lxml.html表單 從Response對象的表單資料預填充表單欄位。
class scrapy.http.FormRequest(url[, formdata, ...])
本FormRequest類增加了新的建構函式的參數。其餘的參數與Request類相同,這裡沒有記錄。 參數:formdata(元組的dict或iterable) - 是一個包含HTML Form資料的字典(或(key,value)元組的迭代),它將被url編碼並分配給請求的主體。
該FormRequest對象支援除標準以下類方法Request的方法:
classmethod from_response(response[, formname=None, formid=None, formnumber=0, formdata=None, formxpath=None, formcss=None, clickdata=None, dont_click=False, ...])
返回一個新FormRequest對象,其中的表單欄位值已預先<form>填充在給定響應中包含的HTML 元素中。有關樣本,請參閱 使用FormRequest.from_response()來類比使用者登入。
該策略是在任何可查看的表單控制項上預設自動類比點擊,如a 。即使這是相當方便,並且經常想要的行為,有時它可能導致難以調試的問題。例如,當使用使用javascript填充和/或提交的表單時,預設行為可能不是最合適的。要禁用此行為,您可以將參數設定 為。此外,如果要更改單擊的控制項(而不是禁用它),您還可以使用 參數。<input type="submit"> from_response() dont_click True clickdata
參數: response(Responseobject) - 包含將用於預填充表單欄位的HTML表單的響應 formname(string) - 如果給定,將使用name屬性設定為此值的形式。 formid(string) - 如果給定,將使用id屬性設定為此值的形式。 formxpath(string) - 如果給定,將使用匹配xpath的第一個表單。 formcss(string) - 如果給定,將使用匹配css選取器的第一個形式。 formnumber(integer) - 當響應包含多個表單時要使用的表單的數量。第一個(也是預設)是0。 formdata(dict) - 要在表單資料中覆蓋的欄位。如果響應<form>元素中已存在欄位,則其值將被在此參數中傳遞的值覆蓋。 clickdata(dict) - 尋找控制項被點擊的屬性。如果沒有提供,表單資料將被提交,類比第一個可點擊元素的點擊。除了html屬性,控制項可以通過其相對於表單中其他提交表輸入的基於零的索引,通過nr屬性來標識。 dont_click(boolean) - 如果為True,表單資料將在不點擊任何元素的情況下提交。
這個類方法的其他參數直接傳遞給 FormRequest建構函式。
在新版本0.10.3:該formname參數。
在新版本0.17:該formxpath參數。
新的版本1.1.0:該formcss參數。
新的版本1.1.0:該formid參數。 請求使用樣本 使用FormRequest通過HTTP POST發送資料
如果你想在你的爬蟲中類比HTML表單POST並發送幾個索引值欄位,你可以返回一個FormRequest對象(從你的爬蟲)像這樣:
return [FormRequest(url="http://www.example.com/post/action", formdata={'name': 'John Doe', 'age': '27'}, callback=self.after_post)] 使用FormRequest.from_response()來類比使用者登入
網站通常通過元素(例如會話相關資料或認證令牌(用於登入頁面))提供預填充的表單欄位。進行剪貼時,您需要自動預填充這些欄位,並且只覆蓋其中的一些,例如使用者名稱和密碼。您可以使用 此作業的方法。這裡有一個使用它的爬蟲樣本:<input type="hidden"> FormRequest.from_response()
import scrapyclass LoginSpider(scrapy.Spider): name = 'example.com' start_urls = ['http://www.example.com/users/login.php'] def parse(self, response): return scrapy.FormRequest.from_response( response, formdata={'username': 'john', 'password': 'secret'}, callback=self.after_login ) def after_login(self, response): # check login succeed before going on if "authentication failed" in response.body: self.logger.error("Login failed") return # continue scraping with authenticated session... 響應對象
class scrapy.http.Response(url[, status=200, headers=None, body=b'', flags=None, request=None])
一個Response對象表示的HTTP響應,這通常是下載(由下載),並供給到爬蟲進行處理。
參數: url(string) - 此響應的URL status(integer) - 響應的HTTP狀態。預設為200。 headers(dict) - 這個響應的頭。dict值可以是字串(對於單值標題)或列表(對於多值標題)。 body(str) - 響應體。它必須是str,而不是unicode,除非你使用一個編碼感知響應子類,如 TextResponse。 flags(list) - 是一個包含屬性初始值的 Response.flags列表。如果給定,列表將被淺複製。 request(Requestobject) - 屬性的初始值Response.request。這代表Request產生此響應。
url
包含響應的URL的字串。
此屬性為唯讀。更改響應使用的URL replace()。
status
表示響應的HTTP狀態的整數。樣本:200, 404。
headers
包含響應標題的類字典對象。可以使用get()返回具有指定名稱的第一個標題值或getlist()返回具有指定名稱的所有標題值來訪問值。例如,此調用會為您提供標題中的所有Cookie:
response.headers.getlist('Set-Cookie')
body
本回複的本文。記住Response.body總是一個位元組對象。如果你想unicode版本使用 TextResponse.text(只在TextResponse 和子類中可用)。
此屬性為唯讀。更改響應使用的主體 replace()。
request
Request產生此響應的對象。在響應和請求通過所有下載中介軟體後,此屬性在Scrapy引擎中分配。特別地,這意味著:
HTTP重新導向將導致將原始請求(重新導向之前的URL)分配給重新導向響應(重新導向後具有最終URL)。
Response.request.url並不總是等於Response.url
此屬性僅在爬蟲程式碼和 Spider Middleware中可用,但不能在Downloader Middleware中使用(儘管您有通過其他方式可用的請求)和處理常式response_downloaded。
meta
的捷徑Request.meta的屬性 Response.request對象(即self.request.meta)。
與Response.request屬性不同,Response.meta 屬性沿重新導向和重試傳播,因此您將獲得Request.meta從您的爬蟲發送的原始屬性。
也可以看看
Request.meta 屬性
flags
包含此響應的標誌的列表。標誌是用於標記響應的標籤。例如:'cached','redirected '等等。它們顯示在Response( str 方法)的字串表示上,它被引擎用於日誌記錄。
copy()
返回一個新的響應,它是此響應的副本。
replace([ url,status,headers,body,request,flags,cls ] )
返回具有相同成員的Response對象,但通過指定的任何關鍵字參數賦予新值的成員除外。該屬性Response.meta是預設複製。
urljoin(url )
通過將響應url與可能的相對URL 組合構造絕對url。
這是一個封裝在urlparse.urljoin,它只是一個別名,使這個調用:
urlparse.urljoin(response.url, url)
響應子類
這裡是可用的內建Response子類的列表。您還可以將Response類子類化以實現您自己的功能。 TextResponse對象
class scrapy.http.TextResponse(url[, encoding[, ...]])
TextResponse對象向基Response類添加編碼能力 ,這意味著僅用於位元據,例如映像,聲音或任何媒體檔案。
TextResponse對象支援一個新的建構函式參數,除了基礎Response對象。其餘的功能與Response類相同,這裡沒有記錄。
參數: encoding(string) - 是一個字串,包含用於此響應的編碼。如果你建立一個TextResponse具有unicode主體的對象,它將使用這個編碼進行編碼(記住body屬性總是一個字串)。如果encoding是None(預設值),則將在響應標題和本文中尋找編碼。
TextResponse除了標準對象之外,對象還支援以下屬性Response
text
響應體,如unicode。
同樣response.body.decode(response.encoding),但結果是在第一次調用後緩衝,因此您可以訪問 response.text多次,無需額外的開銷。
注意
unicode(response.body)不是一個正確的方法來將響應身體轉換為unicode:您將使用系統預設編碼(通常為ascii)而不是響應編碼。
encoding
包含此響應的編碼的字串。編碼通過嘗試以下機制按順序解決: 在建構函式編碼參數中傳遞的編碼 在Content-Type HTTP頭中聲明的編碼。如果此編碼無效(即未知),則會被忽略,並嘗試下一個解析機制。 在響應主體中聲明的編碼。TextResponse類不提供任何特殊功能。然而, HtmlResponse和XmlResponse類做。 通過查看響應體來推斷的編碼。這是更脆弱的方法,但也是最後一個嘗試。
selector
一個Selector使用響應為目標執行個體。選取器在第一次訪問時被延遲執行個體化。
TextResponse對象除了標準對象外還支援以下方法Response:
xpath(查詢)
捷徑TextResponse.selector.xpath(query):
response.xpath('//p')
css(query)
捷徑 TextResponse.selector.css(query):
response.css('p')
body_as_unicode()
同樣text,但可用作方法。保留此方法以實現向後相容; 請喜歡response.text。 HtmlResponse對象
class scrapy.http.HtmlResponse(url [,... ] )
本HtmlResponse類的子類,TextResponse 這增加了通過查看HTML編碼自動探索支援META HTTP-EQUIV屬性。見TextResponse.encoding。 XmlResponse對象
class scrapy.http.XmlResponse(url [,... ] )
本XmlResponse類的子類,TextResponse這增加了通過查看XML聲明線路編碼自動探索支援。見TextResponse.encoding。