搜尋
首頁後端開發Python教學詳解python urllib2用法

詳解python urllib2用法

Sep 04, 2017 pm 01:40 PM
python用法

urllib2是Python的一個獲取URLs(Uniform Resource Locators)的元件。他以urlopen函數的形式提供了一個非常簡單的接口,這是具有利用不同協議獲取URLs的能力,他同樣提供了一個比較複雜的接口來處理一般情況,例如:基礎驗證,cookies,代理和其他。它們透過handlers和openers的物件提供。

urllib2支援取得不同格式的URLs(在URL的":"前定義的字符串,例如:"ftp"是"ftp:python.ort/"的前綴),它們利用它們相關網路協議(例如FTP,HTTP)進行取得。這篇教學關注最廣泛的應用--HTTP。

對於簡單的應用,urlopen是非常容易使用的。但當你在開啟HTTP的URLs時遇到錯誤或異常,你將需要一些超文本傳輸協定(HTTP)的理解。

最權威的HTTP文件當然是RFC 2616(http://rfc.net/rfc2616.html)。這是一個技術文檔,所以並不易於閱讀。這篇HOWTO教學的目的是展現如何使用urllib2,

並提供足夠的HTTP細節來幫助你理解。他並不是urllib2的文檔說明,而是扮演一個輔助角色。

取得URLs

最簡單的使用urllib2

程式碼實例:

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

urllib2的許多應用程式就是那麼簡單(記住,除了"http: ",URL同樣可以用"ftp:","file:"等等來取代)。但這篇文章是教授HTTP的更複雜的應用。

HTTP是基於請求和應答機制的--客戶端提出請求,服務端提供應答。 urllib2用一個Request對象來映射你提出的HTTP請求,在它最簡單的使用形式中你將用你要請求的地址創建一個Request對象,通過調用urlopen並傳入Request對象,將返回一個相關請求response對象,這個應答對像如同一個文件對象,所以你可以在Response中呼叫.read()。

import urllib2 
req = urllib2.Request('http://www.pythontab.com') 
response = urllib2.urlopen(req) 
the_page = response.read()

記得urllib2使用相同的介面處理所有的URL頭。例如你可以像下面那樣建立一個ftp請求。

req = urllib2.Request('ftp://example.com/')

在HTTP請求時,允許你做額外的兩件事。首先是你能夠發送data表單數據,其次你能夠傳送額外的關於數據或發送本身的資訊("metadata")到伺服器,此數據作為HTTP的"headers"來發送。

接下來讓我們看看這些如何發送的。

Data資料

有時候你希望發送一些資料到URL(通常URL與CGI[通用網關介面]腳本,或其他WEB應用程式掛接)。在HTTP中,這個經常使用熟知的POST請求發送。這個通常在你提交一個HTML表單時由你的瀏覽器來做。

並不是所有的POSTs都來自表單,你能夠使用POST提交任意的資料到你自己的程式。一般的HTML表單,data需要編碼成標準形式。然後做為data參數傳到Request物件。編碼工作使用urllib的函數而非urllib2。

程式碼實例:

import urllib 
import urllib2 
url = 'http://www.php.cn' 
values = {'name' : 'Michael Foord', 
          'location' : 'pythontab', 
          'language' : 'Python' } 
data = urllib.urlencode(values) 
req = urllib2.Request(url, data) 
response = urllib2.urlopen(req) 
the_page = response.read()

記住有時需要別的編碼(例如從HTML上傳檔案--看http://www.w3.org/TR/REC-html40/interact/ forms.html#h-17.13 HTML Specification, Form Submission的詳細說明)。

如ugoni沒有傳送data參數,urllib2使用GET方式的請求。 GET和POST請求的不同之處是POST請求通常有"副作用",它們會由於某種途徑改變系統狀態(例如提交成堆垃圾到你的門口)。

儘管HTTP標準說的很清楚POSTs通常會產生副作用,GET請求不會產生副作用,但沒有什麼可以阻止GET請求產生副作用,同樣POST請求也可能不產生副作用。 Data同樣可以透過在Get請求的URL本身上面編碼來傳送。

程式碼實例:

>>> import urllib2 
>>> import urllib 
>>> data = {} 
>>> data['name'] = 'Somebody Here' 
>>> data['location'] = 'pythontab' 
>>> data['language'] = 'Python' 
>>> url_values = urllib.urlencode(data) 
>>> print url_values 
name=blueelwang+Here&language=Python&location=pythontab 
>>> url = 'http://www.pythontab.com' 
>>> full_url = url + '?' + url_values 
>>> data = urllib2.open(full_url)

Headers

我們將在這裡討論特定的HTTP頭,來說明怎麼加入headers到你的HTTP請求。

有一些網站不喜歡被程式(非人為訪問)訪問,或發送不同版本的內容到不同的瀏覽器。預設的urllib2把自己當作「Python-urllib/x.y」(x和y是Python主版本和次版本號,例如Python-urllib/2.5),這個身分可能會讓站點迷惑,或者乾脆不工作。瀏覽器確認自己身分是透過User-Agent頭,當你建立了一個請求對象,你可以給他一個包含頭資料的字典。下面的範例發送跟上面一樣的內容,但把自身

模擬成Internet Explorer。

import urllib 
import urllib2 
url = 'http://www.php.cn' 
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' 
 
values = {'name' : 'Michael Foord', 
          'location' : 'pythontab', 
          '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()

response回應物件同樣有兩個很有用的方法。看下面的節info and geturl,我們將看到當發生錯誤時會發生什麼。

Handle Exceptions處理異常

當urlopen不能夠處理一個response時,產生urlError(不過通常的Python APIs異常如ValueError,TypeError等也會同時產生)。

HTTPError是urlError的子類,通常在特定HTTP URLs中產生。

URLError

通常,URLError在沒有網路連線(沒有路由到特定伺服器),或伺服器不存在的情況下產生。在這種情況下,異常同樣會帶有"reason"屬性,它是一個tuple,包含了一個錯誤號碼和一個錯誤訊息。

例如

>>> req = urllib2.Request('http://www.php.cn') 
>>> try: urllib2.urlopen(req) 
>>> except URLError, e: 
>>>    print e.reason 
>>>

(4, 'getaddrinfo failed') 

HTTPError

服务器上每一个HTTP 应答对象response包含一个数字"状态码"。有时状态码指出服务器无法完成请求。默认的处理器会为你处理一部分这种应答(例如:假如response是一个"重定向",需要客户端从别的地址获取文档,urllib2将为你处理)。其他不能处理的,urlopen会产生一个HTTPError。典型的错误包含"404"(页面无法找到),"403"(请求禁止),和"401"(带验证请求)。

请看RFC 2616 第十节有所有的HTTP错误码

HTTPError实例产生后会有一个整型'code'属性,是服务器发送的相关错误号。

Error Codes错误码

因为默认的处理器处理了重定向(300以外号码),并且100-299范围的号码指示成功,所以你只能看到400-599的错误号码。

BaseHTTPServer.BaseHTTPRequestHandler.response是一个很有用的应答号码字典,显示了RFC 2616使用的所有的应答号。这里为了方便重新展示该字典。

当一个错误号产生后,服务器返回一个HTTP错误号,和一个错误页面。你可以使用HTTPError实例作为页面返回的应答对象response。这表示和错误属性一样,它同样包含了read,geturl,和info方法。

>>> req = urllib2.Request('http://www.php.cn/fish.html') 
>>> try: 
>>>     urllib2.urlopen(req) 
>>> except URLError, e: 
>>>     print e.code 
>>>     print e.read() 
>>>
404 
 
 Error 404: File Not Found 
...... etc...

Wrapping it Up包装

所以如果你想为HTTPError或URLError做准备,将有两个基本的办法。我则比较喜欢第二种。

第一个:

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

注意:except HTTPError 必须在第一个,否则except URLError将同样接受到HTTPError。 

第二个:

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

info and geturl

urlopen返回的应答对象response(或者HTTPError实例)有两个很有用的方法info()和geturl()

geturl -- 这个返回获取的真实的URL,这个很有用,因为urlopen(或者opener对象使用的)或许

会有重定向。获取的URL或许跟请求URL不同。

info -- 这个返回对象的字典对象,该字典描述了获取的页面情况。通常是服务器发送的特定头headers。目前是httplib.HTTPMessage 实例。

经典的headers包含"Content-length","Content-type",和其他。查看Quick Reference to HTTP Headers(http://www.cs.tut.fi/~jkorpela/http.html)获取有用的HTTP头列表,以及它们的解释意义。

Openers和Handlers

当你获取一个URL你使用一个opener(一个urllib2.OpenerDirector的实例,urllib2.OpenerDirector可能名字可能有点让人混淆。)正常情况下,我们使用默认opener -- 通过urlopen,但你能够创建个性的openers,Openers使用处理器handlers,所有的“繁重”工作由handlers处理。每个handlers知道如何通过特定协议打开URLs,或者如何处理URL打开时的各个方面,例如HTTP重定向或者HTTP cookies。

如果你希望用特定处理器获取URLs你会想创建一个openers,例如获取一个能处理cookie的opener,或者获取一个不重定向的opener。

要创建一个 opener,实例化一个OpenerDirector,然后调用不断调用.add_handler(some_handler_instance).

同样,可以使用build_opener,这是一个更加方便的函数,用来创建opener对象,他只需要一次函数调用。

build_opener默认添加几个处理器,但提供快捷的方法来添加或更新默认处理器。

其他的处理器handlers你或许会希望处理代理,验证,和其他常用但有点特殊的情况。

install_opener 用来创建(全局)默认opener。这个表示调用urlopen将使用你安装的opener。

Opener对象有一个open方法,该方法可以像urlopen函数那样直接用来获取urls:通常不必调用install_opener,除了为了方便。

Basic Authentication 基本验证

为了展示创建和安装一个handler,我们将使用HTTPBasicAuthHandler,为了更加细节的描述本主题--包含一个基础验证的工作原理。

请看Basic Authentication Tutorial(http://www.voidspace.org.uk/python/articles/authentication.shtml)

当需要基础验证时,服务器发送一个header(401错误码) 请求验证。这个指定了scheme 和一个‘realm’,看起来像这样:Www-authenticate: SCHEME realm="REALM".

例如

Www-authenticate: Basic realm="cPanel Users"

客户端必须使用新的请求,并在请求头里包含正确的姓名和密码。这是“基础验证”,为了简化这个过程,我们可以创建一个HTTPBasicAuthHandler的实例,并让opener使用这个handler。

HTTPBasicAuthHandler使用一个密码管理的对象来处理URLs和realms来映射用户名和密码。如果你知道realm(从服务器发送来的头里)是什么,你就能使用HTTPPasswordMgr。

通常人们不关心realm是什么。那样的话,就能用方便的HTTPPasswordMgrWithDefaultRealm。这个将在你为URL指定一个默认的用户名和密码。这将在你为特定realm提供一个其他组合时得到提供。我们通过给realm参数指定None提供给add_password来指示这种情况。

最高层次的URL是第一个要求验证的URL。你传给.add_password()更深层次的URLs将同样合适。

# 创建一个密码管理者 
password_mgr = urllib2.HTTPPasswordMgrWithDefaultRealm() 
# 添加用户名和密码 
# 如果知道 realm, 我们可以使用他代替 ``None``. 
top_level_url = "http://php.cn/foo/" 
password_mgr.add_password(None, top_level_url, username, password) 
handler = urllib2.HTTPBasicAuthHandler(password_mgr) 
# 创建 "opener" (OpenerDirector 实例) 
opener = urllib2.build_opener(handler) 
# 使用 opener 获取一个URL 
opener.open(a_url) 
# 安装 opener. 
# 现在所有调用 urllib2.urlopen 将用我们的 opener. 
urllib2.install_opener(opener)

注意:以上的例子我们仅仅提供我们的HHTPBasicAuthHandler给build_opener。默认的openers有正常状况的handlers--ProxyHandler,UnknownHandler,HTTPHandler,HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler, HTTPErrorProcessor。

top_level_url 实际上可以是完整URL(包含"http:",以及主机名及可选的端口号)例如:http://example.com/,也可以是一个“authority”(即主机名和可选的包含端口号)例如:“example.com” or “example.com:8080”(后者包含了端口号)。权限验证,如果递交的话不能包含"用户信息"部分,例如:“joe@password:example.com”是错误的。

Proxies代理urllib 将自动监测你的代理设置并使用他们。这个通过ProxyHandler这个在正常处理器链中的对象来处理。通常,那工作的很好。但有时不起作用。其中一个方法便是安装我们自己的代理处理器ProxyHandler,并不定义代理。这个跟使用Basic Authentication 处理器很相似。

>>> proxy_support = urllib.request.ProxyHandler({}) 
>>> opener = urllib.request.build_opener(proxy_support) 
>>> urllib.request.install_opener(opener)

注意:

此时urllib.request不支持通过代理获取https地址。但,这个可以通过扩展urllib.request达到目的。

Sockets and Layers

Python支持获取网络资源是分层结构。urllib 使用http.client库,再调用socket库实现。

在Python2.3你可以指定socket的等待回应超时时间。这个在需要获取网页的应用程序里很有用。默认的socket模型没有超时和挂起。现在,socket超时没有暴露给http.client或者urllib.request层。但你可以给所有的sockets设置全局的超时。

以上是詳解python urllib2用法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
Python:遊戲,Guis等Python:遊戲,Guis等Apr 13, 2025 am 12:14 AM

Python在遊戲和GUI開發中表現出色。 1)遊戲開發使用Pygame,提供繪圖、音頻等功能,適合創建2D遊戲。 2)GUI開發可選擇Tkinter或PyQt,Tkinter簡單易用,PyQt功能豐富,適合專業開發。

Python vs.C:申請和用例Python vs.C:申請和用例Apr 12, 2025 am 12:01 AM

Python适合数据科学、Web开发和自动化任务,而C 适用于系统编程、游戏开发和嵌入式系统。Python以简洁和强大的生态系统著称,C 则以高性能和底层控制能力闻名。

2小時的Python計劃:一種現實的方法2小時的Python計劃:一種現實的方法Apr 11, 2025 am 12:04 AM

2小時內可以學會Python的基本編程概念和技能。 1.學習變量和數據類型,2.掌握控制流(條件語句和循環),3.理解函數的定義和使用,4.通過簡單示例和代碼片段快速上手Python編程。

Python:探索其主要應用程序Python:探索其主要應用程序Apr 10, 2025 am 09:41 AM

Python在web開發、數據科學、機器學習、自動化和腳本編寫等領域有廣泛應用。 1)在web開發中,Django和Flask框架簡化了開發過程。 2)數據科學和機器學習領域,NumPy、Pandas、Scikit-learn和TensorFlow庫提供了強大支持。 3)自動化和腳本編寫方面,Python適用於自動化測試和系統管理等任務。

您可以在2小時內學到多少python?您可以在2小時內學到多少python?Apr 09, 2025 pm 04:33 PM

兩小時內可以學到Python的基礎知識。 1.學習變量和數據類型,2.掌握控制結構如if語句和循環,3.了解函數的定義和使用。這些將幫助你開始編寫簡單的Python程序。

如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎?如何在10小時內通過項目和問題驅動的方式教計算機小白編程基礎?Apr 02, 2025 am 07:18 AM

如何在10小時內教計算機小白編程基礎?如果你只有10個小時來教計算機小白一些編程知識,你會選擇教些什麼�...

如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到?如何在使用 Fiddler Everywhere 進行中間人讀取時避免被瀏覽器檢測到?Apr 02, 2025 am 07:15 AM

使用FiddlerEverywhere進行中間人讀取時如何避免被檢測到當你使用FiddlerEverywhere...

Python 3.6加載Pickle文件報錯"__builtin__"模塊未找到怎麼辦?Python 3.6加載Pickle文件報錯"__builtin__"模塊未找到怎麼辦?Apr 02, 2025 am 07:12 AM

Python3.6環境下加載Pickle文件報錯:ModuleNotFoundError:Nomodulenamed...

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用