Python模組之urllib和urllib2結合使用
簡介:
urllib2是python的一個獲取url(Uniform
Resource Locators,統一資源定址器)的模組。它用urlopen函式的形式提供了一個非常簡潔的介面。這使得用各種各樣的協議獲取url成為可能。它同時也提供了一個稍微複雜的介面來處理常見的狀況-如基本的認證,cookies,代理,等等。這些都是由叫做opener和handler的物件來處理的。
以下是獲取url最簡單的方式:
import urllib2
response = urllib2.urlopen('http://python.org/')
html = response.read()
許多urlib2的使用都是如此簡單(注意我們本來也可以用一個以
import urllib2
req = urllib2.Request('http://www.voidspace.org.uk')
response = urllib2.urlopen(req)
the_page = response.read()
注意urlib2利用了同樣的Request介面來處理所有的url協議。例如,你可以像這樣請求一個ftpRequest:
req = urllib2.Request('ftp://example.com/')
對於HTTP,Request物件允許你做兩件額外的事:第一,你可以向伺服器傳送資料。第二,你可以向伺服器傳送額外的資訊(metadata),這些資訊可以是關於資料本身的,或者是關於這個請求本身的–這些資訊被當作HTTP頭髮送。讓我們依次看一下這些。
資料:有時你想向一個URL傳送資料(通常這些資料是代表一些CGI指令碼或者其他的web應用)。對於HTTP,這通常叫做一個Post。當你傳送一個你
import urllib
import urllib2
url = 'http://www.someserver.com/cgi-bin/register.cgi'
values = {'name' : 'Michael Foord',
'location' : 'Northampton',
'language' : 'Python' }
data = urllib.urlencode(values)
req = urllib2.Request(url, data)
response = urllib2.urlopen(req)
the_page = response.read()
如果你不傳送資料引數,urlib2使用了一個GET請求。一個GET請求和POST請求的不同之處在於POST請求通常具有邊界效應:它們以某種方式改變系統的狀態。(例如,通過網頁設定一條指令運送一英擔罐裝牛肉到你家。)雖然HTTP標準清楚的說明Post經常產生邊界效應,而get從不產生邊界效應,但沒有什麼能阻止一個get請求產生邊界效應,或一個Post請求沒有任何邊界效應。資料也能被url自己加密(Encoding)然後通過一個get請求傳送出去。
這通過以下實現:
>>> import urllib2
>>> import urllib
>>> data = {}
>>> data['name'] = 'Somebody Here'
>>> data['location'] = 'Northampton'
>>> data['language'] = 'Python'
>>> url_values = urllib.urlencode(data)
>>> print url_values
name=Somebody+Here&language=Python&location=Northampton
>>> url = 'http://www.example.com/example.cgi'
>>> full_url = url + '?' + url_values
>>> data = urllib2.open(full_url)
頭:我們將會在這裡討論一個特殊的HTTP頭,來闡釋怎麼向你的HTTP請求中加入頭。有一些網站不希望被某些程式瀏覽或者針對不同的瀏覽器返回不同的版本。預設情況下,urlib2把自己識別為Python-urllib/x.y(這裡的 xy是python發行版的主要或次要的版本號,如, Python-urllib/2.5),這些也許會混淆站點,或者完全不工作。瀏覽器區別自身的方式是通過User-Agent頭。當你建立一個 Request物件時,你可以加入一個頭字典。接下來的這個例子和上面的請求一樣,不過它把自己定義為IE的一個版本。
import urllib
import urllib2
url = 'http://www.someserver.com/cgi-bin/register.cgi'
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
values = {'name' : 'Michael Foord',
'location' : 'Northampton',
'language' : 'Python' }
headers = { 'User-Agent' : user_agent }
data = urllib.urlencode(values)
req = urllib2.Request(url, data, headers)
response = urllib2.urlopen(req)
the_page = response.read()
Respons同樣有兩種有用的方法。當我們出差錯之後,看一下關於info and geturl的部分。
異常處理:
不能處理一個respons時,urlopen丟擲一個urlerror(雖然像平常一樣對於python
APIs,內建異常如,ValueError, TypeError等也會被丟擲。)
HTTPerror是HTTP URL在特別的情況下被丟擲的URLError的一個子類。
urlerror:通常,urlerror被丟擲是因為沒有網路連線(沒有至特定伺服器的連線)或者特定的伺服器不存在。在這種情況下,含有reason屬性的異常將被丟擲,以一種包含錯誤程式碼和文字錯誤資訊的tuple形式。
e.g.
>>> req = urllib2.Request('http://www.pretend_server.org')
>>> try: urllib2.urlopen(req)
>>> except URLError, e:
>>> print e.reason
>>>
(4, 'getaddrinfo failed')
當一個錯誤被丟擲的時候,伺服器返回一個HTTP錯誤程式碼和一個錯誤頁。你可以使用返回的HTTP錯誤示例。這意味著它不但具有code屬性,而且同時具有read,geturl,和info,methods屬性。>>> req = urllib2.Request('http://www.python.org/fish.html')>>> try:>>> urllib2.urlopen(req)>>> except URLError, e:>>> print e.code>>> print e.read()>>>404...... etc
容錯:如果你準備處理HTTP錯誤和URL錯誤這裡有兩種基本的方法,我更傾向於後一種:
1.
from urllib2 import Request, urlopen, URLError, HTTPError
req = Request(someurl)
try:
response = urlopen(req)
except HTTPError, e:
print 'The server couldn/'t fulfill the request.'
print 'Error code: ', e.code
except URLError, e:
print 'We failed to reach a server.'
print 'Reason: ', e.reason
else:
# everything is fine
注意:HTTP錯誤異常必須在前面,否則URL錯誤也會捕獲一個HTTP錯誤。
2
from urllib2 import Request, urlopen, URLError
req = Request(someurl)
try:
response = urlopen(req)
except URLError, e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'The server couldn/'t fulfill the request.'
print 'Error code: ', e.code
else:
# everything is fine
注意:URL錯誤是IO錯誤異常的一個子類。這意味著你能避免引入(import)URL錯誤而使用:
from urllib2 import Request, urlopen
req = Request(someurl)
try:
response = urlopen(req)
except IOError, e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'The server couldn/'t fulfill the request.'
print 'Error code: ', e.code
else:
# everything is fine
極少數環境下,urllib2能夠丟擲socket.error.
INFO and GETURL
urlopen返回的response(或者HTTP錯誤例項)有兩個有用的方法:info和geturl。
geturl–它返回被獲取網頁的真正的url。這是很有用的,因為urlopen(或使用的opener物件)也許會伴隨一個重定向。獲取的網頁url也許和要求的網頁url不一樣。
info–它返回一個像字典的物件來描述獲取的網頁,尤其是伺服器傳送的頭。它現在一般是httplib.HTTPMessage的一個例項。典型的頭包含'Content-length', 'Content-type', 等等。看一下Quick Reference to HTTP Headers中,HTTP頭列表,還有關於他們簡單的解釋和使用方法。
Openers 和Handlers
當你獲取一個URL時,你使用一個opener(一個可能以一個比較迷糊名字命名的例項–urllib2.OpenerDirector)。正常情況下我們一直使用預設的opener,通過urlopen,但你也可以建立自定義的openers。opener使用操作器(handlers)。所有的重活都交給這些handlers來做。每一個handler知道怎麼開啟url以一種獨特的url協議(http,ftp等等),或者怎麼處理開啟url的某些方面,如,HTTP重定向,或者HTTP
cookie。
你將會建立openers如果你想要用安裝特別的handlers獲取url,例如,獲取一個處理cookie的opener,或者一個不處理重定向的opener。
列舉一個OpenerDirector,然後多次呼叫.add_handler(some_handler_instance)來建立一個opener。或者,你可以用build_opener,這是一個很方便的建立opener物件的函式,它只有一個函式呼叫。build_opener預設會加入許多
handlers,但是提供了一個快速的方法新增更多東西和/或使預設的handler失效。其他你想要的handlers能夠處理代理,authentication和其他平常但是又有些特殊的情況。
install_opener能被用於建立一個opener物件,(全域性)預設的opener。這意味著呼叫urlopen將會用到你剛安裝的opener。
opener物件有一個open方法,它可以被直接呼叫來獲取url以一種和urlopen函式同樣的方式:沒有必要呼叫install_opener,除非是為了方便。
Basic Authentication:(基本驗證)
為了解釋建立和安裝一個handler,我們將會使用 HTTPBasicAuthHandler。更多關於這個東西的內容和詳細討論—包括一個Basic Authentication如何工作的解說–參見 Basic Authentication Tutorial.
當需要Authentication的時候,伺服器傳送一個頭(同時還有401程式碼)請求Authentication。它詳細指明瞭一個Authentication和一個域。這個頭看起來像:
Www-authenticate: SCHEME realm=”REALM”.
e.g.
Www-authenticate: Basic realm=”cPanel Users”
客戶端然後就會用包含在頭中的正確的帳戶和密碼重新請求這個域。這是”基本驗證”。為了簡化這個過程,我們可以建立一個
HTTPBasicAuthHandler和opener的例項來使用這個handler。
HTTPBasicAuthHandler用一個叫做密碼管理的物件來處理url和使用者名稱和密碼的域的對映。如果你知道域是什麼(從伺服器傳送的authentication
頭中),那你就可以使用一個HTTPPasswordMgr。多數情況下人們不在乎域是什麼。那樣使用HTTPPasswordMgrWithDefaultRealm就很方便。它允許你為一個url具體指定使用者名稱和密碼。這將會在你沒有為一個特殊的域提供一個可供選擇的密碼鎖時提供給你。我們通過提供None作為add_password方法域的引數指出這一點。最高級別的url是需要authentication的第一個url。比你傳遞給.add_password()的url更深的url同樣也會匹配。
# create a password manager
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
# Add the username and password.
# If we knew the realm, we could use it instead of “None“.
top_level_url = “http://example.com/foo/”
password_mgr.add_password(None, top_level_url, username, password)
handler = urllib2.HTTPBasicAuthHandler(password_mgr)
# create “opener” (OpenerDirector instance)
opener = urllib2.build_opener(handler)
# use the opener to fetch a URL
opener.open(a_url)
# Install the opener.
# Now all calls to urllib2.urlopen use our opener.
urllib2.install_opener(opener)
注意:在以上的示例中我們只給build_opener提供了HTTPBasicAuthHandler。預設opener有對普通情況的操作器(handlers)-
ProxyHandler, UnknownHandler, HTTPHandler, HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler, HTTPErrorProcessor.
高級別url實際上是一個完整的url(包括http:協議元件和主機名可選的埠號),如”http://example.com”或者是一個授權(同樣,主機名,可選的埠號)如”"example.com” 或 “example.com:8080″(後一個示例包含了一個埠號)。授權,如果被呈現,一定不能包含使用者資訊-如”[email protected]:example.com”
是不正確的、代理:
urllib2將會自動檢測你的代理設定並使用它們。這是通過 ProxyHandler實現的,它是操作器鏈的一部分。正常情況下,這是個好東西,但是也有它不那麼有用的偶然情況。一個做這些的方法是安裝我們自己的ProxyHandler,不用任何定義任何代理。使用一個和建立Basic Authentication操作器相似的步驟可以實現:
>>> proxy_support = urllib2.ProxyHandler({})
>>> opener = urllib2.build_opener(proxy_support)
>>> urllib2.install_opener(opener)
注意:目前urllib2不支援通過代理獲取HTTPs位置。這是一個問題。
sockets和layers
python支援獲取層疊的網頁的原始碼。urllib2使用httplib library,而httplib
library反過來使用socket library。對於python2.3你可以指明一個socket應該在超時之前等待response多久。這在這些不得不獲取網頁的應用中很有用。預設socket模組沒有超時而且能夠掛起。目前,socket超時在urllib2或者httplib水平中不可見。然而,你可以全域性地為所有socket設定預設的超時。
import socket
import urllib2
# timeout in seconds
timeout = 10
socket.setdefaulttimeout(timeout)
# this call to urllib2.urlopen now uses the default timeout
# we have set in the socket module
req = urllib2.Request('http://www.voidspace.org.uk')
response = urllib2.urlopen(req)
相關推薦
Python模組之urllib和urllib2結合使用
簡介: urllib2是python的一個獲取url(Uniform Resource Locators,統一資源定址器)的模組。它用urlopen函式的形式提供了一個非常簡潔的介面。這使得用各種各樣的協議獲取url成為可能。它同時也提供了一個稍微複雜的介面來處理常見的狀
python模組之urllib.request基礎使用
</script> <script type="text/javascript">var Cookie={set:function(e,t,o,i,s,n){document.cookie=e+"="+(n?t:escape(t))+(s?"; expires="+s.toGMTS
Py之urllib2:Python庫之urllib、urllib2、urllib3系列簡介、安裝、使用方法之詳細攻略
urllib2簡介urllib和urllib2之間PK1、在python中,urllib和urllib2不可相互替代的。 整體來說,urllib2是urllib的增強,但是urllib中有urllib2中所沒有的函式。 urllib2可以用urllib2.openu
python urllib 和 urllib2
tran gecko json XML clas nco 接受 這樣的 val urllib 和 urllib2 都是接受URL請求的相關模塊,但是提供了不同的功能。兩個最顯著的不同如下: urllib 僅可以接受URL,不能創建 設置了headers 的Request
Python模組之time:時間獲取和轉換
time 模組 -- 時間獲取和轉換 time模組提供各種時間相關的功能 在 Python 中,與時間處理有關的模組包括:time,datetime 以及 calendar 雖然這個模組總是可用,但並非所有的功能都適用於各個平臺。 該模組中定義的大部分函式是呼叫 C 平臺上的同名函式實現,所以各個平臺上實現可
python模組:xlsxwriter和xlrd相結合讀取、寫入excel檔案
python模組簡單說明: xlsxwriter:負責寫入資料 xlrd:負責讀取資料 xlsxwriter 官方文件:http://xlsxwriter.readthedocs.org 本例項是剛寫出來的,目前比較粗糙。 寫這例項主要是結合平時工作內容,把
python常用模組之json和pickle模組
json模組 json.dumps 將 Python 物件編碼成 JSON 字串 json.loads 用於解碼 JSON 資料。該函式返回 Python 欄位的資料型別。 pick
python的httplib、urllib和urllib2的區別及用
慢慢的把它們總結一下,總結就是最好的學習方法 宗述 首先來看一下他們的區別 urllib和urllib2 urllib 和urllib2都是接受URL請求的相關模組,但是urllib2可以接受一個Re
補充python的urllib和urllib2
此文由我(54snapple)翻譯自http://www.voidspace.org.uk/python/articles/urllib2.shtml。原文標題:urllib2 - The Missing Manual -副標題:HOWTO Fetch Internet Resources with Pyt
Python 正則re模組之compile()和findall()詳解
首先我們看下官方文件裡關於的compile的說明: re.compile(pattern, flags=0) Compile a regular expression pattern into a regular expression object, which can
Python 基礎之列表和元組
bcp rtt fcn ott emd lns swe 二維數組 ttf list Python內置的一種數據類型是列表:list。list是一種有序的集合,可以隨時添加和刪除其中的元素。 比如,列出班裏所有同學的名字,就可以用一個list表示: >>
獨立python環境之virtualenv和virtualenvwrapper
mark then 版本 ret 編輯 bashrc popu exp 影響 介紹 如果有一臺測試機,多個人使用,有多個項目,不同項目可能python版本號不一樣。須要的庫不一樣。我們須要一個獨立幹凈的python環境,互相隔離,互不影響。 virt
python學習之range()和xrange()
python2 har col 叠代 cnblogs 註意 tor 並不是 但是 在python2中,xrange()返回一個xrange對象,註意這個對象並不是生成器,也不是叠代器,但是是叠代對象。 而range()則返回列表對象。 >>> range
Python學習之dict和set
不可變 需要 after 集合 value 報錯 list 也會 如果 #coding=utf-8 # dict dict= {‘bob‘: 40, ‘andy‘: 30} print dict[‘bob‘] # 通過dict提供的get方法,如果key不存在,可以返回N
python基礎之dict和set
算法 dict name 區別 刪除元素 哈希算法 div 數學 blog dict dict是dictionary的縮寫,python內置了字典,在其他語言中也稱為map,使用鍵值對儲存,具有極快的查找速度。 如果是只用list來實現,就需要兩個list,先在第一個lis
python學習之break和continue在for循環中的使用(案例:打印出10以內的偶數,並且只要前三個偶數)
com python學習 bsp 次循環 bubuko python alt info 偶數 運行程序,break是整個程序都跳出 continue則表示跳過當前一次循環,然後繼續執行循環 python學習之break和continue在for循環中的使用(案例:打
Python語法之選擇和迴圈(if、while)
前言:在程式開發中,一共有三種流程方式: 順序:從上向下,順序執行程式碼 分支:根據條件判斷,決定執行程式碼的分支 迴圈:讓特定程式碼重複執行(解決程式設計師重複工作) 1.判斷的定義: 如果條件滿足,才能做某件事 如果條件不滿足,就做另外一件事情,或者什麼也不做 正是有了判斷,才使得程式世界豐富多彩,充滿
python模組之bsddb: bdb高效能嵌入式資料庫
基礎知識 bsddb模組是用來操作bdb的模組,bdb是著名的Berkeley DB,它的效能非常好,mysql的儲存後端引擎都支援bdb的方式。這裡簡單介紹一些關於bsddb的使用方法。 bdb不同於一般的關係資料庫,它儲存的資料只能是以key和value組成的一對資料,使用就像pyt
Python模組之: ConfigParser 配置檔案讀取 Python模組之: ConfigParser 配置檔案讀取
Python模組之: ConfigParser 配置檔案讀取 ConfigParser用於讀寫類似INI檔案的配置檔案,配置檔案的內容可組織為組,還支援多個選項值(option-value)型別。 ConfigParser使用用的配置檔案格式由一個或多個命名的節(s
【轉載】python模組之poplib: 用pop3收取郵件
轉載自: http://www.cnblogs.com/sislcb/archive/2008/12/01/1344858.html python的poplib模組是用來從pop3收取郵件的,也可以說它是處理郵件的第一步。 &nbs