1. 程式人生 > >Python模組之urllib和urllib2結合使用

Python模組之urllib和urllib2結合使用

簡介:
urllib2
python的一個獲取urlUniform Resource Locators,統一資源定址器)的模組。它用urlopen函式的形式提供了一個非常簡潔的介面。這使得用各種各樣的協議獲取url成為可能。它同時也提供了一個稍微複雜的介面來處理常見的狀況-如基本的認證,cookies,代理,等等。這些都是由叫做openerhandler的物件來處理的。

以下是獲取url最簡單的方式:

import urllib2
response = urllib2.urlopen('http://python.org/')
html = response.read()

許多urlib2的使用都是如此簡單(注意我們本來也可以用一個以

”ftp:”"file等開頭的url取代”HTTP”開頭的url.而,這篇教程的目的是解釋關於HTTP更復雜的情形。HTTP建基於請求和迴應(requests &responses -客戶端製造請求伺服器返回迴應。urlib2用代表了你正在請求的HTTP requestRequest物件反映了這些。用它最簡單的形式,你建立了一個Request物件來明確指明你想要獲取的url。呼叫urlopen數對請求的url返回一個respons物件。這個respons是一個像file的物件,這意味著你能用.read()函式操作這個respon物件:

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/')

對於HTTPRequest物件允許你做兩件額外的事:第一,你可以向伺服器傳送資料。第二,你可以向伺服器傳送額外的資訊(metadata),這些資訊可以是關於資料本身的,或者是關於這個請求本身的這些資訊被當作HTTP頭髮送。讓我們依次看一下這些。

資料:有時你想向一個URL傳送資料(通常這些資料是代表一些CGI指令碼或者其他的web應用)。對於HTTP,這通常叫做一個Post。當你傳送一個你

在網上填的form(表單)時,這通常是你的瀏覽器所做的。並不是所有的Post請求都來自HTML表單,這些資料需要被以標準的方式encode,然後作為一個數據引數傳送給Request物件。Encoding是在urlib中完成的,而不是在urlib2中完成的。

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(這裡的 xypython發行版的主要或次要的版本號,如, 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屬性,而且同時具有readgeturl,和infomethods屬性。>>> 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錯誤異常的一個子類。這意味著你能避免引入(importURL錯誤而使用:

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錯誤例項)有兩個有用的方法:infogeturl

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,但你也可以建立自定義的openersopener使用操作器(handlers)。所有的重活都交給這些handlers來做。每一個handler知道怎麼開啟url以一種獨特的url協議(httpftp等等),或者怎麼處理開啟url的某些方面,如,HTTP重定向,或者HTTP cookie

你將會建立openers如果你想要用安裝特別的handlers獲取url,例如,獲取一個處理cookieopener,或者一個不處理重定向的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模組urlliburllib2結合使用

簡介: 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

Pyurllib2Pythonurlliburllib2、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模組:xlsxwriterxlrd相結合讀取、寫入excel檔案

python模組簡單說明: xlsxwriter:負責寫入資料 xlrd:負責讀取資料 xlsxwriter 官方文件:http://xlsxwriter.readthedocs.org 本例項是剛寫出來的,目前比較粗糙。 寫這例項主要是結合平時工作內容,把

python常用模組jsonpickle模組

json模組 json.dumps     將 Python 物件編碼成 JSON 字串 json.loads       用於解碼 JSON 資料。該函式返回 Python 欄位的資料型別。     pick

python的httplib、urlliburllib2的區別及用

慢慢的把它們總結一下,總結就是最好的學習方法 宗述 首先來看一下他們的區別 urllib和urllib2 urllib 和urllib2都是接受URL請求的相關模組,但是urllib2可以接受一個Re

補充pythonurlliburllib2

此文由我(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環境virtualenvvirtualenvwrapper

mark then 版本 ret 編輯 bashrc popu exp 影響 介紹 如果有一臺測試機,多個人使用,有多個項目,不同項目可能python版本號不一樣。須要的庫不一樣。我們須要一個獨立幹凈的python環境,互相隔離,互不影響。 virt

python學習range()xrange()

python2 har col 叠代 cnblogs 註意 tor 並不是 但是 在python2中,xrange()返回一個xrange對象,註意這個對象並不是生成器,也不是叠代器,但是是叠代對象。 而range()則返回列表對象。 >>> range

Python學習dictset

不可變 需要 after 集合 value 報錯 list 也會 如果 #coding=utf-8 # dict dict= {‘bob‘: 40, ‘andy‘: 30} print dict[‘bob‘] # 通過dict提供的get方法,如果key不存在,可以返回N

python基礎dictset

算法 dict name 區別 刪除元素 哈希算法 div 數學 blog dict dict是dictionary的縮寫,python內置了字典,在其他語言中也稱為map,使用鍵值對儲存,具有極快的查找速度。 如果是只用list來實現,就需要兩個list,先在第一個lis

python學習breakcontinue在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