- Scrapy 教程
- Scrapy - 首頁
- Scrapy 基礎概念
- Scrapy - 概述
- Scrapy - 環境配置
- Scrapy - 命令列工具
- Scrapy - 爬蟲 (Spider)
- Scrapy - 選擇器
- Scrapy - 專案 (Item)
- Scrapy - 專案載入器 (Item Loader)
- Scrapy - Shell
- Scrapy - 專案管道 (Item Pipeline)
- Scrapy - 資料匯出 (Feed exports)
- Scrapy - 請求 & 響應
- Scrapy - 連結提取器
- Scrapy - 設定
- Scrapy - 異常處理
- Scrapy 實戰專案
- Scrapy - 建立專案
- Scrapy - 定義專案
- Scrapy - 第一個爬蟲
- Scrapy - 爬取資料
- Scrapy - 提取專案資料
- Scrapy - 使用專案
- Scrapy - 跟蹤連結
- Scrapy - 爬取的資料
- Scrapy 有用資源
- Scrapy - 快速指南
- Scrapy - 有用資源
- Scrapy - 討論
Scrapy - 請求和響應
描述
Scrapy 可以使用Request 和 Response 物件來爬取網站。請求物件在系統中傳遞,使用爬蟲執行請求,並在返回響應物件時返回請求。
請求物件 (Request Objects)
請求物件是一個生成響應的 HTTP 請求。它具有以下類:
class scrapy.http.Request(url[, callback, method = 'GET', headers, body, cookies, meta, encoding = 'utf-8', priority = 0, dont_filter = False, errback])
下表顯示了請求物件的引數:
| 序號 | 引數 & 描述 |
|---|---|
| 1 | url 指定 URL 請求的字串。 |
| 2 | callback 一個可呼叫函式,它使用請求的響應作為第一個引數。 |
| 3 | method 指定 HTTP 方法請求的字串。 |
| 4 | headers 包含請求頭的字典。 |
| 5 | body 包含請求主體的字串或 Unicode 字串。 |
| 6 | cookies 包含請求 Cookie 的列表。 |
| 7 | meta 包含請求元資料的字典。 |
| 8 | encoding 用於編碼 URL 的 utf-8 編碼字串。 |
| 9 | priority 一個整數,排程程式使用優先順序來定義處理請求的順序。 |
| 10 | dont_filter 一個布林值,指定排程程式是否不應過濾請求。 |
| 11 | errback 當處理請求時引發異常時要呼叫的可呼叫函式。 |
將附加資料傳遞給回撥函式
下載響應後,將呼叫請求的回撥函式,其第一個引數為響應。
例如:
def parse_page1(self, response):
return scrapy.Request("http://www.something.com/some_page.html",
callback = self.parse_page2)
def parse_page2(self, response):
self.logger.info("%s page visited", response.url)
如果要將引數傳遞給可呼叫函式並在第二個回撥中接收這些引數,可以使用Request.meta 屬性,如下例所示:
def parse_page1(self, response):
item = DemoItem()
item['foremost_link'] = response.url
request = scrapy.Request("http://www.something.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_link'] = response.url
return item
使用 errback 捕獲請求處理中的異常
errback 是一個可呼叫函式,當處理請求時引發異常時會呼叫它。
以下示例演示了這一點:
import scrapy
from scrapy.spidermiddlewares.httperror import HttpError
from twisted.internet.error import DNSLookupError
from twisted.internet.error import TimeoutError, TCPTimedOutError
class DemoSpider(scrapy.Spider):
name = "demo"
start_urls = [
"http://www.httpbin.org/", # HTTP 200 expected
"http://www.httpbin.org/status/404", # Webpage not found
"http://www.httpbin.org/status/500", # Internal server error
"http://www.httpbin.org:12345/", # 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('Recieved response from {}'.format(response.url))
# ...
def errback_httpbin(self, failure):
# logs failures
self.logger.error(repr(failure))
if failure.check(HttpError):
response = failure.value.response
self.logger.error("HttpError occurred on %s", response.url)
elif failure.check(DNSLookupError):
request = failure.request
self.logger.error("DNSLookupError occurred on %s", request.url)
elif failure.check(TimeoutError, TCPTimedOutError):
request = failure.request
self.logger.error("TimeoutError occurred on %s", request.url)
Request.meta 特殊鍵
request.meta 特殊鍵是由 Scrapy 識別的特殊元鍵列表。
下表顯示了一些 Request.meta 的鍵:
| 序號 | 鍵 & 描述 |
|---|---|
| 1 | dont_redirect 如果設定為 true,則不會根據響應狀態重定向請求。 |
| 2 | dont_retry 如果設定為 true,則不會重試失敗的請求,並將被中介軟體忽略。 |
| 3 | handle_httpstatus_list 定義每個請求允許哪些響應程式碼。 |
| 4 | handle_httpstatus_all 透過將其設定為 true 來允許任何請求的響應程式碼。 |
| 5 | dont_merge_cookies 透過將其設定為 true 來避免與現有 Cookie 合併。 |
| 6 | cookiejar 用於為每個爬蟲保留多個 Cookie 會話。 |
| 7 | dont_cache 用於避免根據每個策略快取 HTTP 請求和響應。 |
| 8 | redirect_urls 包含請求經過的 URL。 |
| 9 | bindaddress 可以用來執行請求的傳出 IP 地址的 IP。 |
| 10 | dont_obey_robotstxt 如果設定為 true,則不會過濾 robots.txt 排除標準禁止的請求,即使啟用了 ROBOTSTXT_OBEY。 |
| 11 | download_timeout 用於為每個爬蟲設定超時時間(以秒為單位),下載器將在其超時前等待。 |
| 12 | download_maxsize 用於為每個爬蟲設定下載器將下載的最大大小(以位元組為單位)。 |
| 13 | proxy 可以為 Request 物件設定代理,以便使用請求設定 HTTP 代理。 |
請求子類 (Request Subclasses)
可以透過子類化請求類來實現自己的自定義功能。內建的請求子類如下:
表單請求物件 (FormRequest Objects)
FormRequest 類透過擴充套件基本請求來處理 HTML 表單。它具有以下類:
class scrapy.http.FormRequest(url[,formdata, callback, method = 'GET', headers, body, cookies, meta, encoding = 'utf-8', priority = 0, dont_filter = False, errback])
引數如下:
formdata - 一個包含分配給請求主體的 HTML 表單資料的字典。
注意 - 其餘引數與請求類相同,在請求物件部分進行了解釋。
除了請求方法外,FormRequest 物件還支援以下類方法:
classmethod from_response(response[, formname = None, formnumber = 0, formdata = None, formxpath = None, formcss = None, clickdata = None, dont_click = False, ...])
下表顯示了上述類的引數:
| 序號 | 引數 & 描述 |
|---|---|
| 1 | response 用於使用響應的 HTML 表單預填充表單欄位的物件。 |
| 2 | formname 一個字串,如果指定,則將使用具有 name 屬性的表單。 |
| 3 | formnumber 當響應中有多個表單時,要使用的表單的整數。 |
| 4 | formdata 用於覆蓋的表單資料中的欄位字典。 |
| 5 | formxpath 一個字串,如果指定,則使用與 xpath 匹配的表單。 |
| 6 | formcss 一個字串,如果指定,則使用與 css 選擇器匹配的表單。 |
| 7 | clickdata 用於觀察被點選控制元件的屬性字典。 |
| 8 | dont_click 如果設定為 true,則將在不點選任何元素的情況下提交表單資料。 |
示例
以下是請求使用的一些示例:
使用 FormRequest 透過 HTTP POST 傳送資料
以下程式碼演示了當您想要在爬蟲中複製 HTML 表單 POST 時如何返回FormRequest 物件:
return [FormRequest(url = "http://www.something.com/post/action",
formdata = {'firstname': 'John', 'lastname': 'dave'},
callback = self.after_post)]
使用 FormRequest.from_response() 模擬使用者登入
通常,網站使用提供預填充表單欄位的元素。
當您希望在抓取時自動填充這些欄位時,可以使用FormRequest.form_response() 方法。
以下示例演示了這一點。
import scrapy
class DemoSpider(scrapy.Spider):
name = 'demo'
start_urls = ['http://www.something.com/users/login.php']
def parse(self, response):
return scrapy.FormRequest.from_response(
response,
formdata = {'username': 'admin', 'password': 'confidential'},
callback = self.after_login
)
def after_login(self, response):
if "authentication failed" in response.body:
self.logger.error("Login failed")
return
# You can continue scraping here
響應物件 (Response Objects)
這是一個表示 HTTP 響應的物件,它被饋送到爬蟲以進行處理。它具有以下類:
class scrapy.http.Response(url[, status = 200, headers, body, flags])
下表顯示了響應物件的引數:
| 序號 | 引數 & 描述 |
|---|---|
| 1 | url 指定 URL 響應的字串。 |
| 2 | status 包含 HTTP 狀態響應的整數。 |
| 3 | headers 包含響應頭的字典。 |
| 4 | body 包含響應主體的字串。 |
| 5 | flags 包含響應標誌的列表。 |
響應子類 (Response Subclasses)
可以透過子類化響應類來實現自己的自定義功能。內建的響應子類如下:
文字響應物件 (TextResponse objects)
TextResponse 物件用於二進位制資料(例如影像、聲音等),它能夠編碼基本 Response 類。它具有以下類:
class scrapy.http.TextResponse(url[, encoding[,status = 200, headers, body, flags]])
引數如下:
encoding - 用於編碼響應的字串編碼。
注意 - 其餘引數與響應類相同,在響應物件部分進行了解釋。
下表顯示了 TextResponse 物件除了響應方法之外還支援的屬性:
| 序號 | 屬性 & 描述 |
|---|---|
| 1 | text 響應主體,response.text 可以多次訪問。 |
| 2 | encoding 包含響應編碼的字串。 |
| 3 | selector 在第一次訪問時例項化的屬性,並使用響應作為目標。 |
下表顯示了除了response 方法之外TextResponse 物件還支援的方法:
| 序號 | 方法 & 描述 |
|---|---|
| 1 | xpath (query) 這是 TextResponse.selector.xpath(query) 的快捷方式。 |
| 2 | css (query) 這是 TextResponse.selector.css(query) 的快捷方式。 |
| 3 | body_as_unicode() 作為方法提供的響應主體,response.text 可以多次訪問。 |
HTML 響應物件 (HtmlResponse Objects)
這是一個支援編碼和自動發現的物件,它透過檢視 HTML 的meta httpequiv 屬性來實現。其引數與響應類相同,在響應物件部分進行了解釋。它具有以下類:
class scrapy.http.HtmlResponse(url[,status = 200, headers, body, flags])
XML 響應物件 (XmlResponse Objects)
這是一個支援編碼和自動發現的物件,它透過檢視 XML 行來實現。其引數與響應類相同,在響應物件部分進行了解釋。它具有以下類:
class scrapy.http.XmlResponse(url[, status = 200, headers, body, flags])