爬蟲學習(二)基礎階段

請求頭中的內容:javascript

  • Date: 標識 響應產生 的時間 。
  • Last-Modified: 指定資源的最後修改時間。
  • Content-Encoding: 指定 響應 內容的編碼 。
  • Server: 包含服務器的信息,好比名稱、版本號等。
  • Content-Type: 文檔類型,指定返回的數據類型是什麼,如 text/html表明返回 HTML文檔,
  • application/x-javascript !J!U表明返回 JavaScript文件, image/jpeg則表明返回圖片 。
  • Set-Cookie: 設置 Cookies。 響應頭 中的 Set-Cookie 告訴瀏覽器須要將此內容放在 Cookies中, 下次請求攜帶 Cookies請求。
  • Expires: 指定響應的過時時間 , 可使代理服務器或瀏覽器將加載的內容更新到緩存。若是再次訪問時,就能夠直接從緩存中加載,下降服務器負載,縮短加載時間。

1.urllib.request模塊

request: 最基本的HTTP請求模塊,能夠用來模擬發送請求。就像在瀏覽器裏輸入網址而後回車同樣,只須要給庫方法傳入 URL 以及額外的參數,就能夠模擬實現這個過程了 ,同時它還帶有處理受權驗證( authenticaton )重定向( redirection)瀏覽器 Cookies 以及其餘內容html

  • error: 異常處理模塊,若是出現請求錯誤,咱們能夠捕獲這些異常,而後進行重試或其餘操做以保證程序不會意外終止 。
  • parse: 一個工具模塊,提供了許多 URL處理方法,好比拆分,解析,合併等。
  • robotparser:主要是用來識別網站的 robots.txt文件,而後判斷哪些網站能夠爬,哪些網站不能夠爬,它其實用得比較少 。

urllib.request.urlopen() 爲最基本HTTP請求的方法java

import urllib.request
response= urllib.request.urlopen('https://www.python.org') 
print(response.read().decode ('utf-8'))  //打印出網頁的源代碼
print(type(response))    //<class ’ http.client.HTTPResponse ’ >說明該對象類型爲HTTPResponse類型。
print(response.status)    //200

print(response.getheaders()) //   
[('Server', 'nginx'), ('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-Options', 'DENY'), 
('Via', '1.1 vegur'), ('Via', '1.1 varnish'), ('Content-Length', '48995'), ('Accept-Ranges', 'bytes'), 
('Date', 'Mon, 13 May 2019 09:23:37 GMT'), ('Via', '1.1 varnish'), ('Age', '3595'), ('Connection', 'close'), 
('X-Served-By', 'cache-iad2139-IAD, cache-tyo19927-TYO'), ('X-Cache', 'HIT, HIT'), 
('X-Cache-Hits', '1, 6071'), ('X-Timer', 'S1557739417.434556,VS0,VE0'), ('Vary', 'Cookie'), 
('Strict-Transport-Security', 'max-age=63072000; includeSubDomains')]

print(response.getheader('Server'))    //nginx

HTTPResposne類型的對象,主要包含python

read()、 readinto()、 getheader(name)、getheaders()、 fileno()等方法,以及 msg、 version、status、reason、debuglevel、closed等屬性。

若是想給連接傳遞一些參數,該怎麼實現呢?首先看一下urlopen()函數的 API:nginx

urllib.request.urlopen(url, data=None, timeout=<object object at 0x1102821a0>, *, cafile=None, capath=None, cadefault=False, context=None)

data參數
data 參數是可選的。 若是要添加該參數,而且若是它是字節流編碼格式的內容,即 bytes 類型, 則須要經過 bytes()方法轉化。 另外,若是傳遞了這個參數,則它的請求方式就再也不是 GET方式,而是POST方式。json

import urllib

data = bytes(urllib.parse.urlencode({'word':'hello'}), encoding='utf8')    //經過utf8的格式將字典進行字節流的編碼,
response= urllib.request.urlopen('http://httpbin.org/post', data=data)        //將編碼後的字節流數據傳輸到指定URL
print(response.read().decode('utf-8'))//這裏存在一個bug,要進行指定方式解碼。

Result:瀏覽器

{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {
    "word": "hello"
  }, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Content-Length": "10", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "httpbin.org", 
    "User-Agent": "Python-urllib/3.6"
  }, 
  "json": null, 
  "origin": "171.81.189.140, 171.81.189.140", 
  "url": "https://httpbin.org/post"
}

• timeout參數
timeout參數用於設置超時時間,單位爲秒,意思就是若是請求超出了設置的這個時間,尚未獲得響應,就會拋出異常。若是不指定該參數,就會使用全局默認時間。它支持HTTP,HTTPS,FTP請求。緩存

import socket
import urllib


try:
    response = urllib.request.urlopen('http://httpbin.org/get', timeout=0.1)  //若是時間超過0.1S不響應就報錯。
except urllib.error.URLError as e:
    if isinstance(e.reason,socket.timeout):
        print("TIME OUT!")

• 其餘參數
除了data參數和timeout參數外,還有context參數,它必須是 ssl.SSLContext類型,用來指定SSL 設置。此外,cafile和 capath這兩個參數分別指定 CA證書和它的路徑,這個在請求 HTTPS連接時會有用。
cadefault參數如今已經棄用了,其默認值爲 False。服務器

2.Request類

import urllib.request

request = urllib.request.Request("https://python.org")
response = urllib .request.urlopen(request)
print(response.read().decode ('utf-8'))

依然是用 urlopen()方法來發送這個請求,只不過該方法的參數再也不是 URL, 而是一個 Request 類型的對象。經過構造這個數據結構,一方面咱們能夠將請求獨立成一個對象,另 一方面可更加豐富和靈活地配置參數 。數據結構

class urllib. request. Request (url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)
  1. 第一個參數url用於請求URL,這是必傳參數,其他可選。
  2. 第二個參數 data 若是要傳,必須傳 bytes (字節流)類型的。若是它是字典,能夠先用 urllib.parse模塊裏的urlencode()編碼。將字典裏面全部的鍵值轉化爲query-string格式(key=value&key=value),而且將中文轉碼。
  3. 第三個參數 headers是一個字典,它就是請求頭,咱們能夠在構造請求時經過 headers參數直 接構造,也能夠經過調用請求實例的 add_header()方法添加。

添加請求頭最經常使用的用法就是經過修改 User-Agent 來假裝瀏覽器,默認的 User-Agent 是Python-urllib,咱們能夠經過修改它來假裝瀏覽器 。 好比要假裝火狐瀏覽器,你能夠把它設置爲 :Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:66.0) Gecko/20100101 Firefox/66.0

  1. 第四個參數 origin_req_host指的是請求方的host名稱或者IP地址。
  2. 第五個參數 unverifiable表示這個請求是不是沒法驗證 的,默認是 False,意思就是說用戶沒有足夠權限來選擇接收這個請求的結果。 例如,咱們請求一個 HTML文檔中的圖片,可是我 們沒有向動抓取圖像的權限,這時unverifiable 的值就是True。
  3. 第六個參數 method是一個字符串 ,用來指示請求使用的方法,好比 GET、 POST和 PUT等

    from urllib import parse,request    
    
    url = 'http://httpbin.org/post'
    headers = {
    'User-Agent':'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
    'Host' :'httpbin.org'
    }
    
    dict={
    'name':'Gremey'
    }
    data= bytes(parse.urlencode(dict), encoding='utf-8')
    
    #req = request.Request(url=url, data=data, headers=headers, method='POST')
    //上面是直接寫好headers傳遞參數傳遞給對象,下面是單獨的經過對象的方法傳遞
    req=request.Request(url=url, data=data, method='POST')
    req.add_header('User-Agent','Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)')
    response = request.urlopen(req)
    print(response.read().decode('utf-8'))

3. 高級用法

在上面的過程當中,咱們雖然能夠構造請求,可是對於一些更高級的操做(好比 Cookies處理 、 代理設置等),該如何處理?
就須要更強大的工具 Handler 登場了。簡而言之,咱們能夠把它理解爲各類處理器,有專門處理登陸驗證的,有處理 Cookies 的,有處理代理設置的。利用它們,咱們幾乎能夠作到 HTTP請求中全部的事。
urllib .request 模塊裏的 BaseHandler類,它是全部其餘 Handler 的父類,它提 供了最基本的方法,例如 default_open()、 protocol_request()等。

接下來,就有各類 Handler 子類繼承這個 BaseHandler類,舉例以下 。

  • HITPDefaultErrorHandler:用於處理HTTP響應錯誤,錯誤都會拋出 HTTPError類型的異常。
  • HTTPRedirectHandler:用於處理重定向。
  • HTTPCookieProcessor: 用於處理 Cookies。
  • ProxyHandler:用於設置代理 , 默認代理爲空 。
  • HπPPasswordMgr:用於管理密碼,它維護了用戶名和密碼的表。
  • HTTPBasicAuthHandler: 用於管理認證,若是一個連接打開時須要認證,那麼能夠用它來解決認證問題。

另外一個比較重要的類就是 OpenerDirector,咱們能夠稱爲 Opener。 咱們以前用過 urlopen()這個方法,實際上它就是urllib爲咱們提供的一個Opener。那麼,爲何要引人Opener 呢?由於須要實現更高級的功能。以前使用的 Request 和 urlopen() 至關於類庫爲你封裝好了極其經常使用的請求方法,利用它們能夠完成基本的請求,可是如今不同了,咱們須要實現更高級的功能,因此須要深刻一層進行配置,使用更底層的實例來完成操做,因此這裏就用到了Opener。Opener可使用 open()方法,返回的類型和urlopen()一模一樣。 那麼,它和 Handler 有什麼關 系呢?簡而言之,就是利用 Handler來構建 Opener。

相關文章
相關標籤/搜索