python requests和urllib_Python——深入理解urllib、urllib2及requests(requests不建議使用?)...

深入理解urllib、urllib2及requests

Python 是一種面向對象、解釋型計算機程序設計語言,由Guido van

Rossum于1989年底發明,第一個公開發行版發行于1991年,Python 源代碼同樣遵循 GPL(GNU General Public

License)協議[1] 。Python語法簡潔而清晰,具有豐富和強大的類庫。

urllib and urllib2 區別

urllib和urllib2模塊都做與請求URL相關的操作,但他們提供不同的功能。

urllib2.urlopen accepts

an instance of the Request class or a url, (whereas urllib.urlopen only

accepts a url

中文意思就是:urllib2.urlopen可以接受一個Request對象或者url,(在接受Request對象時候,并以此可以來設置一個URL

的headers),urllib.urlopen只接收一個url

urllib 有urlencode,urllib2沒有,這也是為什么總是urllib,urllib2常會一起使用的原因r?=?Request(url='http://www.mysite.com')

r.add_header('User-Agent',?'awesome?fetcher')

r.add_data(urllib.urlencode({'foo':?'bar'})

response?=?urllib2.urlopen(r)?????#post?method

urllib 模塊

I. urlencode不能直接處理unicode對象,所以如果是unicode,需要先編碼,有unicode轉到utf8,舉例:urllib.urlencode?(u'bl'.encode('utf-8'))

II. 示例import?urllib???????#sohu?手機主頁

url?=?'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_smuid=\

ICvXXapq5EfTpQTVq6Tpz'

resp?=?urllib.urlopen(url)

page?=?resp.read()

f?=?open('./urllib_index.html',?'w')

f.write(page)

print?dir(resp)

結果:['doc',?'init',?'iter',?'module',?'repr',?'close',?'code',?'fileno',?'fp',?'getcode',?'geturl',?'headers',?'info',?'next',?'read',?'readline',?'readlines',?'url']

print?resp.getcode(),?resp.geturl(),?resp.info(),?resp.headers,?resp.url

#resp.url和resp.geturl()結果一樣

III. 編解碼示例 urllib.quote和urllib.urlencode都是編碼,但用法不一樣48?????s?=?urllib.quote('This?is?python')??#編碼?49?????print?'quote:\t'+s????#空格用%20替代?50?????s_un?=?urllib.unquote(s)????#解碼?51?????print?'unquote:\t'+s_un?52?????s_plus?=?urllib.quote_plus('This?is?python')??#編碼?53?????print?'quote_plus:\t'+s_plus????????????#空格用+替代?54?????s_unplus?=?urllib.unquote_plus(s_plus)???????#解碼?55?????print?'s_unplus:\t'+s_unplus?56?????s_dict?=?{'name':?'dkf',?'pass':?'1234'}?57?????s_encode?=?urllib.urlencode(s_dict)????#編碼字典轉換成url參數

58?????print?'s_encode:\t'+s_encode

結果:quote:?This%20is%20python

unquote:???This?is?python

quote_plus:????This+is+python

s_unplus:??This?is?python

s_encode:??name=dkf&pass=1234

IV. urlretrieve() urlretrieve多數適用單純的只下載的功能或者顯示下載的進度等75?????url?=?'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_\

smuid=ICvXXapq5EfTpQTVq6Tpz'

76?????urllib.urlretrieve(url,?'./retrieve_index.html')

#直接把url鏈接網頁內容下載到retrieve_index.html里了,適用于單純的下載的功能。

#urllib.urlretrieve(url,?local_name,?method)

urllib2

I. urllib2模塊定義的函數和類用來獲取URL(主要是HTTP的),他提供一些復雜的接口用于處理:

基本認證,重定向,Cookies等。 II. 常用方法和類 II.1 urllib2.urlopen(url[, data][,

timeout]) #傳url時候,用法同urllib里的urlopen II.1.1

它打開URL網址,url參數可以是一個字符串url或者是一個Request對象。可選的參數timeout,阻塞操作以秒為單位,如嘗試連接(如果沒

有指定,將使用設置的全局默認timeout值)。實際上這僅適用于HTTP,HTTPS和FTP連接。85?????url?=?'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_\

smuid=ICvXXapq5EfTpQTVq6Tpz'86?????resp?=?urllib2.urlopen(url)87?????page?=?resp.read()

II.1.2

urlopen方法也可通過建立了一個Request對象來明確指明想要獲取的url。調用urlopen函數對請求的url返回一個response對

象。這個response類似于一個file對象,所以用.read()函數可以操作這個response對象url?=?'http://m.sohu.com/?v=3&_once_=000025_v2tov3&_smuid\

=ICvXXapq5EfTpQTVq6Tpz'

req?=?urllib2.Request(url)

resp?=?urllib2.urlopen(req)

page?=?resp.read()

II.2 class urllib2.Request(url[, data][, headers][, originreqhost][, unverifiable])

II.2.1 Request類是一個抽象的URL請求。5個參數的說明如下: II.2.1.1

URL——是一個字符串,其中包含一個有效的URL。 II.2.1.2

data——是一個字符串,指定額外的數據發送到服務器,如果沒有data需要發送可以為“None”。目前使用data的HTTP請求是唯一的。當請求

含有data參數時,HTTP的請求為POST,而不是GET。數據應該是緩存在一個標準的application/x-www-form-

urlencoded格式中。urllib.urlencode()函數用映射或2元組,返回一個這種格式的字符串。通俗的說就是如果想向一個URL發送

數據(通常這些數據是代表一些CGI腳本或者其他的web應用)。例如在網上填的form(表單)時,瀏覽器會POST表單的內容,這些數據需要被以標準

的格式編碼(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)???#send?post

response?=?urllib2.urlopen(req)

page?=?response.read()

II.2.1.3

headers——是字典類型,頭字典可以作為參數在request時直接傳入,也可以把每個鍵和值作為參數調用add_header()方法來添加。作

為辨別瀏覽器身份的User-Agent

header是經常被用來惡搞和偽裝的,因為一些HTTP服務只允許某些請求來自常見的瀏覽器而不是腳本,或是針對不同的瀏覽器返回不同的版本。例

如,Mozilla Firefox瀏覽器被識別為“Mozilla/5.0 (X11; U; Linux i686) Gecko/20071127

Firefox/2.0.0.11”。默認情況下,urlib2把自己識別為Python-urllib/x.y(這里的xy是python發行版的主要

或次要的版本號,如在Python

2.6中,urllib2的默認用戶代理字符串是“Python-urllib/2.6。下面的例子和上面的區別就是在請求時加了一個headers,模

仿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()

標準的headers組成是(Content-Length, Content-Type and

Host),只有在Request對象調用urlopen()(上面的例子也屬于這個情況)或者OpenerDirector.open()時加入。兩種

情況的例子如下:

使用headers參數構造Request對象,如上例在生成Request對象時已經初始化header,而下例是Request對象調用

add_header(key, val)方法附加header(Request對象的方法下面再介紹):import?urllib2

req?=?urllib2.Request('http://www.example.com/')

req.add_header('Referer',?'http://www.python.org/')

#http是無狀態的協議,上一次客戶端的請求與下一次客戶端到服務器的請求無關系的,多數省略這一步

r?=?urllib2.urlopen(req)

OpenerDirector為每一個Request自動加上一個User-Agent header,所以第二種方法如下(urllib2.buildopener會返回一個OpenerDirector對象,關于urllib2.buildopener類下面再說):import?urllib2

opener?=?urllib2.build_opener()

opener.addheaders?=?[('User-agent',?'Mozilla/5.0')]

opener.open('http://www.example.com/')

II.3 urllib2.installopener(opener)和urllib2.buildopener([handler, ...])

installopener和buildopener這兩個方法通常都是在一起用,也有時候buildopener單獨使用來得到OpenerDirector對象。

installopener

實例化會得到OpenerDirector

對象用來賦予全局變量opener。如果想用這個opener來調用urlopen,那么就必須實例化得到OpenerDirector;這樣就可以簡單

的調用OpenerDirector.open()來代替urlopen()。

build_opener實例化也會得到

OpenerDirector對象,其中參數handlers可以被BaseHandler或他的子類實例化。子類中可以通過以下實例

化:ProxyHandler (如果檢測代理設置用)掃描代理會用到,很重要這個, UnknownHandler, HTTPHandler,

HTTPDefaultErrorHandler, HTTPRedirectHandler, FTPHandler, FileHandler,

HTTPErrorProcessor。import?urllib2

req?=?urllib2.Request('http://www.python.org/')

opener=urllib2.build_opener()

urllib2.install_opener(opener)

f?=?opener.open(req)

如上使用 urllib2.install_opener()設置 urllib2 的全局

opener。這樣后面的使用會很方便,但不能做更細粒度的控制,比如想在程序中使用兩個不同的 Proxy 設置等。比較好的做法是不使用

install_opener 去更改全局的設置,而只是直接調用 opener的open 方法代替全局的 urlopen 方法。

說到這Opener和Handler之間的操作聽起來有點暈。整理下思路就清楚了。當獲取一個URL時,可以使用一

個opener(一個urllib2.OpenerDirector實例對象,可以由build_opener實例化生成)。正常情況下程

序一直通過urlopen使用默認的opener(也就是說當你使用urlopen方法時,是在隱式的使用默認的opener

對象),但也可以創建自定義的openers(通過操作 器handlers創建的opener實例)。所有的重活和麻煩

都交給這些handlers來做。每一個handler知道如何以一種特定的協議(http,ftp等等)打開url,或

者如何處理打開url發生的HTTP重定向,或者包含的HTTP cookie。創建openers時如果想要安裝特別的han

dlers來實現獲取url(如獲取一個處理cookie的opener,或者一個不處理重定向的opener)的話,先實例

一個OpenerDirector對象,然后多次調用.add_handler(some_handler_instance)來創建一個opene

r。或者,你可以用build_opener,這是一個很方便的創建opener對象的函數,它只有一個函數調用

。build_opener默認會加入許多handlers,它提供了一個快速的方法添加更多東西和使默認的handler 失效。

install_opener如上所述也能用于創建一個opener對象,但是這個對象是(全局)默認的opener。這意味著調用urlopen

將會用到你剛創建的opener。也就是說上面的代碼可以等同于下面這段。這段代碼最終還是使用的默認opener。一般情況下我們用

build_opener為的是生成自定義opener,沒有必要調用install_opener,除非是為了方便。import?urllib2

req?=?urllib2.Request('http://www.python.org/')

opener=urllib2.build_opener()???????#?創建opener對象

urllib2.install_opener(opener)??????#定義全局默認opener

f?=?urllib2.urlopen(req)??????????#urlopen使用默認opener,但是install_opener

#已經把opener設為全局默認了,這里便是使用上面的建立的opener

III. 異常處理http://www.jb51.net/article/63711.htm當我們調用urllib2.urlopen的時候不會總是這么順利,就像瀏覽器打開url時有時也會報 錯,所以就需要我們有應對異常的處理。說到異常,我們先來了解返回的response對象的 幾個常用的方法:

geturl() — 返回檢索的URL資源,這個是返回的真正url,通常是用來鑒定是否重定向的

info() — 返回頁面的原信息就像一個字段的對象, 如headers,它以mimetools.Message實例為格式(可以參考HTTP Headers說明)。

getcode()

— 返回響應的HTTP狀態代碼,運行下面代碼可以得到code=200

當不能處理一個response時,urlopen拋出一個URLError(對于python APIs,內建異常如,ValueError,

TypeError 等也會被拋出。)HTTPError是HTTP

URL在特別的情況下被拋出的URLError的一個子類。下面就詳細說說URLError和HTTPError。

URLError——handlers當運行出現問題時(通常是因為沒有網絡連接也就是沒有路由到指定的服務器,或在指定的服務器不存在)

HTTPError——HTTPError是URLError的子類。每個來自服務器HTTP的response都包含“status

code”. 有時status code不能處理這個request.

默認的處理程序將處理這些異常的responses。例如,urllib2發現response的URL與你請求的URL不同時也就是發生了重定向時,會

自動處理。對于不能處理的請求, urlopen將拋出 - - - HTTPError異常. 典型的錯誤包含‘404’ (沒有找到頁面),

‘403’ (禁止請求),‘401’ (需要驗證)等。它包含2個重要的屬性reason和code。

程序對于重定向時默認處理的

總結

如果只是單純的下載或者顯示下載進度,不對下載后的內容做處理等,比如下載圖片,css,js文件等,可以用urlilb.urlretrieve()

如果是下載的請求需要填寫表單,輸入賬號,密碼等,建議用urllib2.urlopen(urllib2.Request())

在對字典數據編碼時候,用到的是urllib.urlencode()

requests

I. Requests 使用的是

urllib3,繼承了urllib2的所有特性。Requests支持HTTP連接保持和連接池,支持使用cookie保持會話,支持文件上傳,支持自

動確定響應內容的編碼,支持國際化的 URL 和 POST 數據自動編碼。 II. 舉例:import?requests

...

resp?=?requests.get('http://www.mywebsite.com/user')

userdata?=?{"firstname":?"John",?"lastname":?"Doe",?"password":?"jdoe123"}

resp?=?requests.post('http://www.mywebsite.com/user',?params=userdata)

resp?=?requests.put('http://www.mywebsite.com/user/put')

resp?=?requests.delete('http://www.mywebsite.com/user/delete')

resp.json()???#?假如返回的是json數據

resp.text?????#返回的不是text數據

resp.headers['content-type']??#返回text/html;charset=utf-8

f?=?open('request_index.html',?'w')

f.write(page.encode('utf8'))

#test?發現requests抓下來的頁面必須要編碼\

#寫入,(抓下來的是unicode),urllib和urllib2抓下來可以直接寫入,

#因為這兩者抓下來的page是str

III. 其他功能特性國際化域名和?URLs

Keep-Alive?&?連接池

持久的?Cookie?會話

類瀏覽器式的?SSL?加密認證

基本/摘要式的身份認證

優雅的鍵/值?Cookies

自動解壓

Unicode?編碼的響應體

多段文件上傳

連接超時

支持?.netrc

適用于?Python?2.6—3.4線程安全

IV. requests不是python自帶的庫,需要另外安裝 easy_install or pip install

V. requests缺陷:直接使用不能異步調用,速度慢(from others)。官方的urllib可以替代它。

VI. 個人不建議使用requests模塊

更詳細的相關介紹

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/542475.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/542475.shtml
英文地址,請注明出處:http://en.pswp.cn/news/542475.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ssh查找linux端口,linux – 查找當前連接的端口號SSH

我正在使用SSH連接創建一個本地模擬器(未連接到Internet).我已經開始使用特定范圍的端口號進行sshd,并對一系列設備進行NAT處理.我必須找到當前連接的端口號.OS CentOS 5.5OpenSSH 6.1我做了以下事情.它適用于正常使用(手動用戶).但是當嘗試嚴格的測試(自動化)時,似乎有時找不到…

this.getstate_Java線程類Thread.State getState()方法(帶示例)

this.getstate線程類Thread.State getState() (Thread Class Thread.State getState()) This method is available in package java.lang.Thread.getState(). 軟件包java.lang.Thread.getState()中提供了此方法。 This method is used to return the state of this thread. 此方…

Java資源大全中文版(Awesome最新版)

來源:http://www.cnblogs.com/best/p/5876559.html 目錄 業務流程管理套件字節碼操作集群管理代碼分析編譯器生成工具構建工具外部配置工具約束滿足問題求解程序持續集成CSV解析數據庫數據結構時間日期工具庫依賴注入開發流程增強工具分布式應用分布式數據庫發布文檔…

運用多種設計模式的綜合案例_SpreadJS 純前端表格控件應用案例:表格數據管理平臺...

由某科技公司研發的表格數據管理平臺,是一款面向業務和企業管理系統定制開發的應用平臺,包括類 Excel 設計器、PC應用端和移動應用端等應用模塊。該平臺具備強大的業務配置和集成開發能力,對于企業客戶的信息系統在管理模式、業務流程、表單界…

linux定位哪個進程出發重啟,定位Linux下定位進程被誰KILL

hezhaoaqiang2012-11-09 11:10可以請教你一個問題嗎?關于arm的交叉編譯。我是按照:http://blog.chinaunix.net/uid-27003388-id-3276139.html 去做的,但是走到 四、建立初始編譯器(bootstrap gcc)下面的make install 它提示如下:m…

Java Integer類numberOfLeadingZeros()方法的示例

整數類numberOfLeadingZeros()方法 (Integer class numberOfLeadingZeros() method) numberOfLeadingZeros() method is available in java.lang package. 在java.lang包中提供了numberOfLeadingZeros()方法 。 numberOfLeadingZeros() method is used to returns the number o…

VS中C++ 項目重命名

應該都有過這樣的經歷,在Visual studio中創建解決方案,添加幾個項目進去,然后開始愉快的敲代碼...。寫代碼正歡的時候,卻總是感覺那里有些不舒服,一細看,這項目名稱取的真心挫,修改個吧。直接右…

Java GregorianCalendar getActualMinimum()方法與示例

GregorianCalendar類getActualMinimum()方法 (GregorianCalendar Class getActualMinimum() method) getActualMinimum() method is available in java.util package. getActualMinimum()方法在java.util包中可用。 getActualMinimum() method is used to get the actual minim…

axure9數據統計插件_WMDA:大數據技術棧的綜合實踐

一、概述WMDA是58自主開發的用戶行為分析產品,同時也是一款支持無埋點的數據采集產品,只需要在第一次使用的時候加載一段SDK代碼,即可采集全量、實時的PC、M、APP三端以及小程序的用戶行為數據。同時,為了滿足用戶個性化的數據采集…

Java Collections unmodifiableCollection()方法與示例

集合類unmodifiableCollection()方法 (Collections Class unmodifiableCollection() method) unmodifiableCollection() method is available in java.util package. unmodifiableCollection()方法在java.util包中可用。 unmodifiableCollection() method is used to get an un…

openfoam安裝中出現allmake error_如何更新OpenFOAM的版本?

這是協作翻譯的第四章,翻譯完感覺挺有意思的,分享給大家一起看看。4.更新OpenFOAM版本4.1 版本管理OpenFOAM以兩種不同的方式分發。一種方式是使用Git倉庫下載的倉庫版本。倉庫版本的版本號由附加的x標記,例如 OpenFOAM2.1.x。該版本會經常更…

java 根據類名示例化類_Java類類的requiredAssertionStatus()方法和示例

java 根據類名示例化類類的類requiredAssertionStatus()方法 (Class class desiredAssertionStatus() method) desiredAssertionStatus() method is available in java.lang package. requiredAssertionStatus()方法在java.lang包中可用。 desiredAssertionStatus() method is …

python中計算排列組合的函數_Python實現的排列組合計算操作示例

本文實例講述了Python實現的排列組合計算操作。分享給大家供大家參考,具體如下:1. 調用 scipy 計算排列組合的具體數值>> from scipy.special import comb, perm>> perm(3, 2)6.0>> comb(3, 2)3.02. 調用 itertools 獲取排列組合的全部…

java日歷類add方法_Java日歷setMinimalDaysInFirstWeek()方法與示例

java日歷類add方法日歷類setMinimalDaysInFirstWeek()方法 (Calendar Class setMinimalDaysInFirstWeek() method) setMinimalDaysInFirstWeek() method is available in java.util package. setMinimalDaysInFirstWeek()方法在java.util包中可用。 setMinimalDaysInFirstWeek(…

相同布局在不同手機上顯示不同_不懂響應式,不同尺寸屏幕下的頁面很難達到最佳效果...

讓用戶在不同設備和尺寸的屏幕下看的頁面顯示效果更佳,屏幕空間利用更高,操作體驗更統一,交互方式更符合習慣。本文主要圍繞什么是響應式,如何搭建響應系統,響應式網站解析 三個部分進行闡述,在項目中提前定…

Java ByteArrayInputStream markSupported()方法與示例

ByteArrayInputStream類markSupported()方法 (ByteArrayInputStream Class markSupported() method) markSupported() method is available in java.util package. markSupported()方法在java.util包中可用。 markSupported() method is used to check whether this ByteArrayI…

markdown 流程圖_測試了12款Markdown編輯器,推薦一個最好用的!

有很多喜歡寫博客的小伙伴問我,這個代碼筆記的格式怎么弄的簡潔又好看,雖然csdn里面有Markdown的書寫模式,但是我還是想推薦一款比較好用的寫筆記的編輯器 - Typora。相信很多小伙伴都在使用吧,這個一直是我最喜歡的 markdown 編輯…

小程序 || 語句_C ++條件語句| 查找輸出程序| 套裝2

小程序 || 語句Program 1: 程序1&#xff1a; #include <iostream>#include <stdio.h>using namespace std;int main(){int num 0;num printf("%d ", printf("%d ", printf("ABC")));if (num 2) {cout << "INDIA&quo…

python爬取天氣預報源代碼_python抓取天氣并分析 實例源碼

【實例簡介】Python代碼抓取獲取天氣預報信息源碼講解。這是一個用Python編寫抓取天氣預報的代碼示例&#xff0c;用python寫天氣查詢軟件程序很簡單。這段代碼可以獲取當地的天氣和、任意城市的天氣預報&#xff0c;原理是根據url找到網站截取相應的數據展現。python抓取廣州天…

Linux編譯程序源碼環境,Linux下對nodejs環境進行源碼編譯并部署云應用

Node 是一個讓 JavaScript 運行在服務端的開發平臺&#xff0c;它讓 JavaScript 成為與PHP、Python、Perl、Ruby 等服務端語言平起平坐的腳本語言。該環境安裝非常簡單&#xff0c;這里簡單記錄下linux(centos環境下)的源碼安裝&#xff0c;做個記錄。平臺&#xff1a;centos 6…