零基礎(chǔ)寫python爬蟲之urllib2中的兩個(gè)重要概念:Openers和Handlers
在開始后面的內(nèi)容之前,先來解釋一下urllib2中的兩個(gè)個(gè)方法:info / geturl
urlopen返回的應(yīng)答對象response(或者HTTPError實(shí)例)有兩個(gè)很有用的方法info()和geturl()
1.geturl():
這個(gè)返回獲取的真實(shí)的URL,這個(gè)很有用,因?yàn)閡rlopen(或者opener對象使用的)或許會有重定向。獲取的URL或許跟請求URL不同。
以人人中的一個(gè)超級鏈接為例,
我們建一個(gè)urllib2_test10.py來比較一下原始URL和重定向的鏈接:
from urllib2 import Request, urlopen, URLError, HTTPError
old_url = 'http://rrurl.cn/b1UZuP'
req = Request(old_url)
response = urlopen(req)
print 'Old url :' + old_url
print 'Real url :' + response.geturl()
運(yùn)行之后可以看到真正的鏈接指向的網(wǎng)址:
2.info():
這個(gè)返回對象的字典對象,該字典描述了獲取的頁面情況。通常是服務(wù)器發(fā)送的特定頭headers。目前是httplib.HTTPMessage 實(shí)例。
經(jīng)典的headers包含"Content-length","Content-type",和其他內(nèi)容。
我們建一個(gè)urllib2_test11.py來測試一下info的應(yīng)用:
from urllib2 import Request, urlopen, URLError, HTTPError
old_url = 'http://www.baidu.com'
req = Request(old_url)
response = urlopen(req)
print 'Info():'
print response.info()
運(yùn)行的結(jié)果如下,可以看到頁面的相關(guān)信息:
下面來說一說urllib2中的兩個(gè)重要概念:Openers和Handlers。
1.Openers:
當(dāng)你獲取一個(gè)URL你使用一個(gè)opener(一個(gè)urllib2.OpenerDirector的實(shí)例)。
正常情況下,我們使用默認(rèn)opener:通過urlopen。
但你能夠創(chuàng)建個(gè)性的openers。
2.Handles:
Openers使用處理器handlers,所有的“繁重”工作由handlers處理。
每個(gè)handlers知道如何通過特定協(xié)議打開URLs,或者如何處理URL打開時(shí)的各個(gè)方面。
例如HTTP重定向或者HTTP cookies。
如果你希望用特定處理器獲取URLs你會想創(chuàng)建一個(gè)openers,例如獲取一個(gè)能處理cookie的opener,或者獲取一個(gè)不重定向的opener。
要?jiǎng)?chuàng)建一個(gè) opener,可以實(shí)例化一個(gè)OpenerDirector,
然后調(diào)用.add_handler(some_handler_instance)。
同樣,可以使用build_opener,這是一個(gè)更加方便的函數(shù),用來創(chuàng)建opener對象,他只需要一次函數(shù)調(diào)用。
build_opener默認(rèn)添加幾個(gè)處理器,但提供快捷的方法來添加或更新默認(rèn)處理器。
其他的處理器handlers你或許會希望處理代理,驗(yàn)證,和其他常用但有點(diǎn)特殊的情況。
install_opener 用來創(chuàng)建(全局)默認(rèn)opener。這個(gè)表示調(diào)用urlopen將使用你安裝的opener。
Opener對象有一個(gè)open方法。
該方法可以像urlopen函數(shù)那樣直接用來獲取urls:通常不必調(diào)用install_opener,除了為了方便。
說完了上面兩個(gè)內(nèi)容,下面我們來看一下基本認(rèn)證的內(nèi)容,這里會用到上面提及的Opener和Handler。
Basic Authentication 基本驗(yàn)證
為了展示創(chuàng)建和安裝一個(gè)handler,我們將使用HTTPBasicAuthHandler。
當(dāng)需要基礎(chǔ)驗(yàn)證時(shí),服務(wù)器發(fā)送一個(gè)header(401錯(cuò)誤碼) 請求驗(yàn)證。這個(gè)指定了scheme 和一個(gè)‘realm',看起來像這樣:Www-authenticate: SCHEME realm="REALM".
例如
Www-authenticate: Basic realm="cPanel Users"
客戶端必須使用新的請求,并在請求頭里包含正確的姓名和密碼。
這是“基礎(chǔ)驗(yàn)證”,為了簡化這個(gè)過程,我們可以創(chuàng)建一個(gè)HTTPBasicAuthHandler的實(shí)例,并讓opener使用這個(gè)handler就可以啦。
HTTPBasicAuthHandler使用一個(gè)密碼管理的對象來處理URLs和realms來映射用戶名和密碼。
如果你知道realm(從服務(wù)器發(fā)送來的頭里)是什么,你就能使用HTTPPasswordMgr。
通常人們不關(guān)心realm是什么。那樣的話,就能用方便的HTTPPasswordMgrWithDefaultRealm。
這個(gè)將在你為URL指定一個(gè)默認(rèn)的用戶名和密碼。
這將在你為特定realm提供一個(gè)其他組合時(shí)得到提供。
我們通過給realm參數(shù)指定None提供給add_password來指示這種情況。
最高層次的URL是第一個(gè)要求驗(yàn)證的URL。你傳給.add_password()更深層次的URLs將同樣合適。
說了這么多廢話,下面來用一個(gè)例子演示一下上面說到的內(nèi)容。
我們建一個(gè)urllib2_test12.py來測試一下info的應(yīng)用:
# -*- coding: utf-8 -*-
import urllib2
# 創(chuàng)建一個(gè)密碼管理者
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
# 添加用戶名和密碼
top_level_url = " # 如果知道 realm, 我們可以使用他代替 ``None``.
# password_mgr.add_password(None, top_level_url, username, password)
password_mgr.add_password(None, top_level_url,'why', '1223')
# 創(chuàng)建了一個(gè)新的handler
handler = urllib2.HTTPBasicAuthHandler(password_mgr)
# 創(chuàng)建 "opener" (OpenerDirector 實(shí)例)
opener = urllib2.build_opener(handler)
a_url = 'http://www.baidu.com/'
# 使用 opener 獲取一個(gè)URL
opener.open(a_url)
# 安裝 opener.
# 現(xiàn)在所有調(diào)用 urllib2.urlopen 將用我們的 opener.
urllib2.install_opener(opener)
注意:以上的例子我們僅僅提供我們的HHTPBasicAuthHandler給build_opener。
默認(rèn)的openers有正常狀況的handlers:ProxyHandler,UnknownHandler,HTTPHandler,HTTPDefaultErrorHandler, HTTPRedirectHandler,F(xiàn)TPHandler, FileHandler, HTTPErrorProcessor。
代碼中的top_level_url 實(shí)際上可以是完整URL(包含"http:",以及主機(jī)名及可選的端口號)。
例如:http://example.com/。
也可以是一個(gè)“authority”(即主機(jī)名和可選的包含端口號)。
例如:“example.com” or “example.com:8080”。
后者包含了端口號。
相關(guān)文章
python tqdm 實(shí)現(xiàn)滾動條不上下滾動代碼(保持一行內(nèi)滾動)
這篇文章主要介紹了python tqdm 實(shí)現(xiàn)滾動條不上下滾動代碼(保持一行內(nèi)滾動),具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02python實(shí)現(xiàn)企業(yè)微信定時(shí)發(fā)送文本消息的示例代碼
這篇文章主要介紹了python實(shí)現(xiàn)企業(yè)微信定時(shí)發(fā)送文本消息的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Django框架 Pagination分頁實(shí)現(xiàn)代碼實(shí)例
這篇文章主要介紹了Django框架 Pagination分頁實(shí)現(xiàn)代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09使用python測試prometheus的實(shí)現(xiàn)
本文主要介紹了使用python測試prometheus的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-02-02Python數(shù)字圖像處理代數(shù)之加減乘運(yùn)算
這篇文章主要介紹了Python數(shù)字圖像處理代數(shù)運(yùn)算,對其中的加、減、乘運(yùn)算分別作了詳細(xì)的講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-09-09python爬蟲開發(fā)之Beautiful Soup模塊從安裝到詳細(xì)使用方法與實(shí)例
這篇文章主要介紹了python爬蟲開發(fā)之Beautiful Soup模塊詳細(xì)使用方法與實(shí)例,需要的朋友可以參考下2020-03-03