作者:zarten,網際網路一線工作者。
地址:zhihu.com/people/zarten
介紹
Request類是一個http請求的類,對於爬蟲而言是一個很重要的類。通常在Spider中創建這樣的一個請求,在Downloader中執行這樣的一個請求。同時也有一個子類FormRequest繼承於它,用於post請求。
在Spider中通常用法:
yield scrapy.Request(url = 'zarten.com')
類屬性和方法有:
url
method
headers
body
meta
copy()
replace([url, method, headers, body, cookies, meta, encoding, dont_filter, callback, errback])
Request
class scrapy.http.Request(url[, callback, method='GET', headers, body, cookies, meta, encoding='utf-8', priority=0, dont_filter=False, errback, flags])
參數說明:
url 請求的url
callback 回調函數,用於接收請求後的返回信息,若沒指定,則默認為parse()函數
method http請求的方式,默認為GET請求,一般不需要指定。若需要POST請求,用FormRequest即可
headers 請求頭信息,一般在settings中設置即可,也可在middlewares中設置
body str類型,為請求體,一般不需要設置(get和post其實都可以通過body來傳遞參數,不過一般不用)
cookies dict或list類型,請求的cookie dict方式(name和value的鍵值對):
cookies = {'name1' : 'value1' , 'name2' : 'value2'}
list方式:
cookies = [
{'name': 'Zarten', 'value': 'my name is Zarten', 'domain': 'example.com', 'path': '/currency'}
]
encoding 請求的編碼方式,默認為'utf-8'
priority int類型,指定請求的優先級,數字越大優先級越高,可以為負數,默認為0
dont_filter 默認為False,若設置為True,這次請求將不會過濾(不會加入到去重隊列中),可以多次執行相同的請求
errback 拋出錯誤的回調函數,錯誤包括404,超時,DNS錯誤等,第一個參數為Twisted Failure實例
from scrapy.spidermiddlewares.httperror import HttpError
from twisted.internet.error import DNSLookupError
from twisted.internet.error import TimeoutError, TCPTimedOutError
class ToScrapeCSSSpider(scrapy.Spider):
name = "toscrape-css"
# start_urls = [
# 'http://quotes.toscrape.com/',
# ]
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.info(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.info('HttpError錯誤 on %s', response.url)
elif failure.check(DNSLookupError):
# this is the original request
request = failure.request
self.logger.info('DNSLookupError錯誤 on %s', request.url)
elif failure.check(TimeoutError, TCPTimedOutError):
request = failure.request
self.logger.info('TimeoutError錯誤 on %s', request.url)
yield scrapy.Request(url = 'zarten.com', meta = {'name' : 'Zarten'})
在Response中:
my_name = response.meta['name']
不過也有scrapy內置的特殊key,也非常有用,它們如下:
可以設置http或https代理
request.meta['proxy'] = 'https://' + 'ip:port'
downloadtimeout 設置請求超時等待時間(秒),通常在settings中設置DOWNLOADTIMEOUT,默認是180秒(3分鐘)
maxretrytimes 最大重試次數(除去第一次下載),默認為2次,通常在settings中 RETRY_TIMES設置
dont_redirect 設為True後,Request將不會重定向
dont_retry 設為True後,對於http連結錯誤或超時的請求將不再重試請求
handlehttpstatuslist http返回碼200-300之間都是成功的返回,超出這個範圍的都是失敗返回,scrapy默認是過濾了這些返回,不會接收這些錯誤的返回進行處理。不過可以自定義處理哪些錯誤返回:
yield scrapy.Request(url= 'https://httpbin.org/get/zarten', meta= {'handle_httpstatus_list' : [404]})
在parse函數中可以看到處理404錯誤:
def parse(self, response):
print('返回信息為:',response.text)
handlehttpstatusall 設為True後,Response將接收處理任意狀態碼的返回信息
dontmergecookies scrapy會自動保存返回的cookies,用於它的下次請求,當我們指定了自定義cookies時,如果我們不需要合併返回的cookies而使用自己指定的cookies,可以設為True
cookiejar 可以在單個spider中追蹤多個cookie,它不是粘性的,需要在每次請求時都帶上
def start_requests(self):
urls = ['http://quotes.toscrape.com/page/1',
'http://quotes.toscrape.com/page/3',
'http://quotes.toscrape.com/page/5',
]
for i ,url in enumerate(urls):
yield scrapy.Request(url= url, meta= {'cookiejar' : i})
def parse(self, response):
next_page_url = response.css("li.next > a::attr(href)").extract_first()
if next_page_url is not None:
yield scrapy.Request(response.urljoin(next_page_url), meta= {'cookiejar' : response.meta['cookiejar']}, callback= self.parse_next)
def parse_next(self, response):
print('cookiejar:', response.meta['cookiejar'])
dont_cache 設為True後,不會緩存
redirect_urls 暫時還不清楚具體的作用,知道的小夥伴們歡迎在評論留言
bindaddress 綁定輸出IP
dontobeyrobotstxt 設為True,不遵守robots協議,通常在settings中設置
downloadmaxsize 設置下載器最大下載的大小(字節),通常在settings中設置DOWNLOADMAXSIZE,默認為1073741824 (1024MB=1G),若不設置最大的下載限制,設為0
download_latency 只讀屬性,獲取請求的響應時間(秒)
def start_requests(self):
headers = {
'user-agent' : 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
yield scrapy.Request(url= 'https://www.amazon.com', headers= headers)
def parse(self, response):
print('響應時間為:', response.meta['download_latency'])
FormRequest
FormRequest 類為Request的子類,用於POST請求
這個類新增了一個參數 formdata,其他參數與Request一樣,詳細可參考上面的講述
一般用法為:
yield scrapy.FormRequest(url="http://www.example.com/post/action",
formdata={'name': 'Zarten', 'age': '27'},
callback=self.after_post)
Python中文社區作為一個去中心化的全球技術社區,以成為全球20萬Python中文開發者的精神部落為願景,目前覆蓋各大主流媒體和協作平臺,與阿里、騰訊、百度、微軟、亞馬遜、開源中國、CSDN等業界知名公司和技術社區建立了廣泛的聯繫,擁有來自十多個國家和地區數萬名登記會員,會員來自以公安部、工信部、清華大學、北京大學、北京郵電大學、中國人民銀行、中科院、中金、華為、BAT、谷歌、微軟等為代表的政府機關、科研單位、金融機構以及海內外知名公司,全平臺近20萬開發者關注。
點擊閱讀原文,從零開始學習Python網絡爬蟲