1.爬蟲 urlib庫講解 Handler高階用法

那是個好男孩發表於2019-04-09

在前面我們總結了urllib庫的 urlopen()和Request()方法的使用,在這一小節我們要使用相關的Handler來實現代理、cookies等功能。

寫在前面:

urlopen()方法不支援代理、cookie等其它的HTTP/GTTPS高階功能,所以要支援這些功能:

  1. 使用相關的Handler處理器來建立特定功能的處理器物件
  2. 然後呼叫urllib.request.build_opener()方法使用這些處理器物件,建立自己的opener物件
  3. 使用自定義的opener物件,呼叫open()方法傳送請求

*如果程式裡所有的請求都使用自定義的opener,可以使用urllib.request.install_opener()將自定義的opener物件定義為全域性的opener,表示如果之後凡是呼叫urlopen(),都將使用這個opener

 

簡單介紹下request模組裡的相關的Handler類:(我們暫且只會用到3種,需求夠了就ok)

  • ProxyHandler:用於設定代理,預設代理為空
  • HTTPCookieProcessor:用於處理Cookies
  • HTTPBasicAuthHandler:用於管理驗證,如果一個連結開啟時需要認證,那麼可以用它來解決認證問題

0.代理伺服器的設定

import urllib.request
import urllib.error

proxy_handler = urllib.request.ProxyHandler({
    'http': 'http://127.0.0.1:9743',
    'https': 'https://127.0.0.1:9743'
})
opener = urllib.request.build_opener(proxy_handler)
try:
    response = opener.open('http://httpbin.org/get')
except URLError as e:
    print(response.read())

當然,我們可以建立全域性預設的opener物件,呼叫urlopen()來傳送請求:

import urllib.request

proxy_handler = urllib.request.ProxyHandler({
    'http': 'http://127.0.0.1:9743',
    'https': 'https://127.0.0.1:9743'
})
opener = urllib.request.build_opener(proxy_handler)
urllib.request.install_opener(opener) #建立全域性預設的opener物件
response = urllib.request.urlopen('http://httpbin.org/get')
print(response.read().decode('utf-8'))

 

1.cookie

簡單說一說cookie相關的知識:cookies庫,該模組(簡單來說,一個.py檔案就可以稱作一個模組)主要的物件有CookJar、FileCookJar、MozillaCookJar、LwPCookJar.

*其實在大多數的情況下,我們只使用CookJar(),如果需要和本地檔案互動,就要用MozillaCookJar()或者LwPCookJar().

*CookJar:管理HTTP、cookie值,儲存HTTP請求生成的Cookie.向傳出的Http請求新增cookie物件。整個cookie都儲存在記憶體中,對CookieJar例項進行垃圾回收後Cookies也會丟失。

(以百度為例,我們將網站的cookies獲取下來並以檔案格式儲存再讀取並利用)

  • 將網站的cookie獲取下來
import http.cookiejar, urllib.request

cookie = http.cookiejar.CookieJar()
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
for item in cookie:
    print(item.name+"="+item.value)

結果如下:

BAIDUID=D45F880AC3EE43897AC101C8E9E48006:FG=1
BIDUPSID=D45F880AC3EE43897AC101C8E9E48006
H_PS_PSSID=1434_21081_28768_28724_28558_28832_28585_26350_28603_28627_28606
PSTM=1554791586
delPer=0
BDSVRTM=0
BD_HOME=0

 

  • 獲取網站的cookies並以文字格式儲存
import http.cookiejar, urllib.request
filename
= "cookie.txt" cookie = http.cookiejar.MozillaCookieJar(filename) handler = urllib.request.HTTPCookieProcessor(cookie) opener = urllib.request.build_opener(handler) response = opener.open('http://www.baidu.com') cookie.save(ignore_discard=True, ignore_expires=True)

*MozillaCookieJar()是CookieJar的子類,可以用來處理Cookies和檔案相關的事件,比如讀取和儲存cookies,可以將cookies儲存成Mozilla型瀏覽器的Cookies格式

*LwPCookJar()同樣可以讀取和儲存cookies,它會儲存成libwww-per(LWP)格式的Cookies檔案

import http.cookiejar, urllib.request
filename
= 'cookie.txt' cookie = http.cookiejar.LWPCookieJar(filename) handler = urllib.request.HTTPCookieProcessor(cookie) opener = urllib.request.build_opener(handler) response = opener.open('http://www.baidu.com') cookie.save(ignore_discard=True, ignore_expires=True)
  • 生成了cookies檔案後,從檔案中讀取並利用(以LWP格式為例)
import http.cookiejar, urllib.request
cookie = http.cookiejar.LWPCookieJar()
cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
handler = urllib.request.HTTPCookieProcessor(cookie)
opener = urllib.request.build_opener(handler)
response = opener.open('http://www.baidu.com')
print(response.read().decode('utf-8'))

 

2.驗證

驗證:有些網站在開啟時就會彈出提示框,直接提示你輸入使用者名稱和密碼,驗證成功後才能檢視頁面。

from urllib.request import HTTPPasswordMgrWithDefaultRealm,HTTPBasicAuthHandler,build_opener
from urllib.error import URLError

username = 'username'
password = 'password'
url = 'http://localhost:5000/'

p = HTTPPasswordMgrWithDefaultRealm()
p.add_password(None,url,username,password)
auth_handler = HTTPBasicAuthHandler(p)
opener = build_opener(auth_handler)

try:
    result = opener.open(url)
    html = result.read().decode('utf-8')
    print('html')
except URLError as e:
    print(e.reason)

 

相關文章