python中的urllib模組中的方法
python urllib.request之urlopen函式
urllib是基於http的高層庫,它有以下三個主要功能:
(1)request處理客戶端的請求
(2)response處理服務端的響應
(3)parse會解析url
下面討論的是request
urllib.request模組定義了一些開啟URLs(一般是HTTP協議)複雜操作像是basic 和摘要模式認證,重定向,cookies等的方法和類。這個模組式模擬檔案模組實現的,將本地的檔案路徑改為遠端的url。因此函式返回的是類檔案物件(file-like object)
urllib.request.urlopen(url, data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)
url可以是一個字串形式或者Request 物件
如果data引數有值就是用post方式響應否則預設為GET 方式
urllib.request 模組使用HTTP/1.1 的無連線的狀態協議
urlopen()函式返回類檔案物件,提供以下內建方法:
- read() , readline() ,readlines() , fileno() , close() :這些方法的使用方式與檔案物件完全一樣
- info():返回一個httplib.HTTPMessage物件,表示遠端伺服器返回的頭資訊
- getcode():返回Http狀態碼。(詳情參考https://tools.ietf.org/html/rfc7231#section-6)
如果是http請求:
1xx(informational):請求已經收到,正在進行中
2xx(successful):請求成功接收,解析,完成
3xx(Redirection):需要重定向
4xx(Client Error):客戶端問題,請求存在語法錯誤,網址未找到
5xx(Server Error):伺服器問題
- geturl():返回請求的url
#!/opt/yrd_soft/bin/python
import re
import urllib2
import requests
import lxml
from bs4 import BeautifulSoup
url = 'http://www.baidu.com'
#page=urllib2.urlopen(url)
page=requests.get(url).text
pagesoup=BeautifulSoup(page,'lxml')
for link in pagesoup.find_all(name='a',attrs={"href":re.compile(r'^http:')}):
print link.get_text()
通過BeautifulSoup庫的get_text方法找到網頁的正文:
#!/usr/bin/env python
#coding=utf-8
#HTML找出正文
import requests
from bs4 import BeautifulSoup
url='http://www.baidu.com'
html=requests.get(url)
soup=BeautifulSoup(html.text)
print soup.get_text()
1 urllib2 簡介
urllib2是python自帶的一個訪問網頁及本地檔案的庫。
與urllib相比,顯著區別之處在於:
1) urllib2可以接受一個Request類的例項來設定URL請求的headers,urllib僅可以接受URL。這意味著,用urllib時不可以偽裝User Agent字串等。
2) urllib提供urlencode方法用來encode傳送的data,而urllib2沒有。這是為何urllib常和urllib2一起使用的原因。
2 urllib2 常用方法
2.1 urllib2.urlopen
urlopen()是最簡單的請求方式,它開啟url並返回類檔案物件,並且使用該物件可以讀取返回的內容
urllib2.urlopen(url[, data][, timeout])
引數:
url: 可以是包含url的字串,也可以是urllib2.request類的例項。
data: 是經過編碼的post資料(一般使用urllib.urlencode()來編碼)。
沒有data引數時為GET請求,設定data引數時為POST請求
timeout: 是可選的超時期(以秒為單位),設定請求阻塞的超時時間,如果沒有設定的話,會使用全域性預設timeout引數,該引數只對HTTP、HTTPS、FTP生效
假設urlopen()返回的檔案物件u,它支援下面的這些常用的方法:
u.read([nbytes]) 以位元組字串形式讀取nbytes個數據
u.readline() 以位元組字串形式讀取單行文字
u.readlines() 讀取所有輸入行然後返回一個列表
u.close() 關閉連結
u.getcode() 返回整數形式的HTTP響應程式碼,比如成功返回200,未找到檔案時返回404
u.geturl() 返回所返回的資料的實際url,但是會考慮發生的重定向問題
u.info() 返回對映物件,該物件帶有與url關聯的資訊。
對HTTP來說,返回的伺服器響應包含HTTP包頭。
對於FTP來說,返回的報頭包含'content-length'。
對於本地檔案,返回的報頭包含‘content-length’和'content-type'欄位。
注意:
類檔案物件u以二進位制模式操作。如果需要以文字形式處理響應資料,則需要使用codecs模組或類似
方式解碼資料。
附程式碼:
>>> import urllib2
>>> res=urllib2.urlopen('http://www.51cto.com')
>>>res.read()
。。。。。。(一堆原始碼)
>>>res.readline()
'<!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0
Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r\n'
>>>res.readlines()
。。。(list形式的一堆原始碼)
>>>res.info()
<httplib.HTTPMessage instance at0x1a02638>
>>>res.getcode()
200
>>>res.geturl()
'http://www.51cto.com'
#最後關閉連線
>>> res.close()
2.2 urllib2.request
新建Request例項
Request (url [data,headers[,origin_req_host ,[unverifiable]]]])
說明:
對於比較簡單的請求,urlopen()的引數url就是一個代表url的,但如果需要執行更復雜的操作,如修改HTTP報頭,可以建立Request例項並將其作為url引數
引數:
url: 為url字串,
data: 是伴隨url提交的資料(比如要post的資料)。不過要注意,提供data引數時,它會將HTTP請求從'GET'改為‘POST’。
headers: 是一個字典,包含了可表示HTTP報頭的鍵值對映(即要提交的header中包含的內容)。
origin_req_host: 通常是發出請求的主機的名稱,如果請求的是無法驗證的url(通常是指不是使用者直接輸入的url,比如載入影象的頁面中鑲入的url),則後一個引數unverifiable設為TRUE
假設Request例項r,其比較重要的方法有下面幾個:
r.add_data(data) 向請求新增資料。如果請求是HTTP請求,則方法改為‘POST’。
data是向指定url提交的資料,要注意該方法不會將data追教導之前已經設定的任何資料上,而是使用現在的data替換之前的。
r.add_header(key, val) 向請求新增header資訊,key是報頭名,val是報頭值,兩個引數都是字串。
r.addunredirectedheader(key,val) 作用基本同上,但不會新增到重定向請求中。
r.set_proxy(host, type) 準備請求到伺服器。使用host替換原來的主機,使用type替換原來的請求型別。
附程式碼:
1 向網頁提交資料:
>>> import urllib
>>> import urllib2
>>> url='http://www.51cto.com'
>>> info={'name':"51cto",'location':'51cto'}
#info需要被編碼為urllib2能理解的格式,這裡用到的是urllib
>>> data=urllib.urlencode(info)
>>> data
'name=51cto&location=51cto'
>>> request=urllib2.Request(url,data)
>>> response=urllib2.urlopen(request)
>>> the_page=response.read()
2 修改網頁頭資訊:
有時會碰到,程式也對,但是伺服器拒絕你的訪問。這是為什麼呢?問題出在請求中的頭資訊(header)。 有的服務端有潔癖,不喜歡程式來觸控它。這個時候你需要將你的程式偽裝成瀏覽器來發出請求。請求的方式就包含在header中。
在使用 REST 介面時,Server 會檢查Content-Type欄位,用來確定 HTTP Body 中的內容該怎樣解析。
>>> import urllib
>>> import urllib2
>>> url='http://www.51cto.com'
# 將user_agent寫入頭資訊
>>> user_agent='Mozilla/4.0 (compatible; MSIE 5.5; WindowsNT)'
>>>values={'name':'51cto','location':"51cto",'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()
2.3 異常處理
不能處理一個respons時,urlopen丟擲一個urlerror
urllib2.URLError:
urllib2.HTTPError:
HTTPerror是HTTP URL在特別的情況下被丟擲的URLError的一個子類。
urlerror:
通常,urlerror被丟擲是因為沒有網路 連線(沒有至特定伺服器的連線)或者特定的伺服器不存在。在這種情況下,含有reason屬性的異常將被丟擲,以一種包含錯誤程式碼 和文字錯誤資訊的tuple形式。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import urllib2
#多寫了一個 m (comm)
req = urllib2.Request('http://www.51cto.comm')
try:
urllib2.urlopen(req)
except urllib2.URLError,e:
print e
print e.reason
結果:
python之web模組學習,基本上涉及常用的的web模組,包括 urllib、urllib2、httplib、urlparse、requests,現在,開始我們的第一個模組的學習吧。
1 urllib簡介
python urllib 模組提供了一個從指定的URL地址獲取網頁資料,然後對其進行分析處理,獲取我們想要的資料。
2 常用方法
2.1 urlopen -- 建立一個類檔案物件 為讀取指定的URL
help(urllib.urlopen)
urlopen(url, data=None, proxies=None)
Create a file-like object for the specified URL to read from.
引數:
url :表示遠端資料的路徑,一般是http或者ftp路徑。
data :表示以get或者post方式提交到url的資料。
proxies :表示用於代理的設定。
Python 通過urlopen函式來獲取html資料,urlopen返回一個類檔案物件,它提供瞭如下常用方法:
1)read() , readline() , readlines(),fileno()和close():這些方法的使用與檔案物件完全一樣。
2)info():返回一個httplib.HTTPMessage 物件,表示遠端伺服器返回的頭資訊。
3)getcode():返回Http狀態碼,如果是http請求,200表示請求成功完成;404表示網址未找到。
4)geturl():返回請求的url地址。
附程式碼:
>>> import urllib
>>> response = urllib.urlopen('http://www.51cto.com')
>>>res.read()
。。。。。。(一堆網頁程式碼)
>>>res.readline()
'<!DOCTYPE html PUBLIC "-//W3C//DTDXHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\r\n'
。。。。
>>>res.readlines()
。。。(list形式的一堆網頁程式碼)
>>>res.info()
<httplib.HTTPMessage instance at0x1a02638>
>>> response.getcode() # 返回Http狀態碼
200
>>> response.geturl() # 返回請求的url地址
'http://www.51cto.com'
>>> response.close() # 最後別忘了關閉連線
urllib中還提供了一些輔助方法,用於對url進行編碼、解碼。url中是不能出現一些特殊的符號的,有些符號有特殊的用途。我們知道以get方式提交資料的時候,會在url中新增key=value這樣的字串,所以在value中是不允許有'=',因此要對其進行編碼;與此同時伺服器接收到這些引數的時候,要進行解碼,還原成原始的資料。這個時候,這些輔助方法會很有用:
附帶的其他方法:(主要是url編碼解碼)
- urllib.quote(string[, safe]):對字串進行編碼。引數safe指定了不需要編碼的字元
- urllib.unquote(string) :對字串進行解碼
- urllib.quote_plus(string [ , safe ] ) :與urllib.quote類似,但這個方法用'+'來替換' ',而quote用'%20'來代替' '
- urllib.unquote_plus(string ) :對字串進行解碼
- urllib.urlencode(query[, doseq]):將dict或者包含兩個元素的元組列表轉換成url引數。例如 字典{'name': 'wklken', 'pwd':'123'}將被轉換為"name=wklken&pwd=123" (常用)
#這裡可以與urlopen結合以實現post方法和get方法
- urllib.pathname2url(path):將本地路徑轉換成url路徑
- urllib.url2pathname(path):將url路徑轉換成本地路徑
附程式碼:
>>> import urllib
>>>res = urllib.quote('I am 51cto')
>>> res
'I%20am%2051cto'
>>>urllib.unquote(res)
'I am 51cto'
>>>res = urllib.quote_plus('I am 51cto')
>>> res
'I+am+51cto'
>>>urllib.unquote_plus(res)
'I am 51cto'
>>> params = {'name':'51cto','pwd':'51cto'}
>>>urllib.urlencode(params)
'pwd=51cto&name=51cto'
>>>l2u=urllib.pathname2url('E:\51cto')
'E%3A%29cto'
>>>urllib.url2pathname(l2u)
'E:)cto'
2.2 urlretrieve -- 直接將遠端的資料下載到本地
help(urllib.urlretrieve)
urlretrieve(url, filename=None,reporthook=None, data=None)
引數:
url :指定下載的URL
finename :指定了儲存本地路徑(如果引數未指定,urllib會生成一個臨時檔案儲存資料。
reporthook :是一個回撥函式,當連線上伺服器、以及相應的資料塊傳輸完畢時會觸發該回調,我們可以利用這個回撥函式來顯示當前的下載進度。
data: 表示post到伺服器的資料,該方法返回一個包含兩個元素的(filename,headers)元組,
下面是一個 urlretrieve方法下載檔案的例項,可以顯示下載進度:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import urllib
import os
def schedule(a,b,c):
''' 回撥函式
@a:已經下載的資料
@b:資料塊的大小
@c:遠端檔案的大小
'''
per = 100.0 * a * b / c
if per > 100:
per = 100
print "%.2f%%" % per
url = 'http://www.python.org/ftp/python/2.7.5/Python-2.7.5.tar.bz2'
local = os.path.join('c:','Python-2.7.5.tar.bz2')
urllib.urlretrieve(url,local,schedule)
2.3 urlcleanup -- 清除由於urllib.urlretrieve()所產生的快取
通過上面的練習可以知道,urlopen可以輕鬆獲取遠端html頁面資訊,然後通過python正則對所需要的資料進行分析,匹配出想要用的資料,然後利用urlretrieve將資料下載到本地。對於訪問受限或者對連線數有限制的遠端url地址可以採用proxies(代理的方式)連線,如果遠端資料量過大,單執行緒下載太慢的話可以採用多執行緒下載,這個就是傳說中的爬蟲。
上面介紹的前兩個方法是urllib中最常用的方法,這些方法在獲取遠端資料的時候,內部會使用URLopener或者 FancyURLOpener類。作為urllib的使用者,我們很少會用到這兩個類。如果對urllib的實現感興趣,或者希望urllib支援更多的協議,可以研究這兩個類
urllib2是python自帶的模組,有簡單請求方法,也有複雜的http驗證,http代理方法,今天就介紹幾個基本的http請求方法。
urllib2的urlopen方法可以直接新增url即可訪問,但是此方法不支援驗證和代理的方法,所以後邊會介紹urllib2的Request類和opener
urllib2.urlopen
urllib2.urlopen(url,data=None,timeout=1,cafile=None,capath=None,cadefault=False,context=None)
下面是urllib2發起http請求,獲取httpcode
In [1]: import urllib2
In [2]: url = 'http://test.nginxs.net/index.html'
In [3]: res = urllib2.urlopen(url)
#讀取請求結果
In [5]: print res.read()
this is index.html
#獲取httpcode
In [6]: print res.code
200
#獲取http請求頭
In [7]: print res.headers
Server: nginxsweb
Date: Sat, 07 Jan 2017 02:42:10 GMT
Content-Type: text/html
Content-Length: 19
Last-Modified: Sat, 07 Jan 2017 01:04:12 GMT
Connection: close
ETag: "58703e8c-13"
Accept-Ranges: bytes
urllib2的Request
(self, url, data=None, headers={}, origin_req_host=None, unverifiable=False)
通過http請求傳送資料給zabbix登入(非api的登入)
import urllib
import urllib2
url = 'http://192.168.198.116/index.php'
#這裡是zabbix的賬戶,密碼,和點選的操作
data = {'name' : 'admin',
'password' : 'zabbix',
'enter' : 'Sign in' }
#編碼上面的資料
data = urllib.urlencode(data)
#例項化Request類
req = urllib2.Request(url, data)
#傳送請求
response = urllib2.urlopen(req)
the_page = response.read()
print the_page
urllib2.HTTPBasicAuthHandler
驗證nginx的使用者進行登入
#初始化一個auth_handler例項它的功能是http驗證的類
auth_handler = urllib2.HTTPBasicAuthHandler()
top_level_url = 'http://test.nginxs.net/limit/views.html'
username='admin'
password='nginxs.net'
#呼叫auth_handler例項裡面的密碼方法
auth_handler.add_password(realm='Nginxs.net login',uri='
#構建一個opener 物件,它將使用http,https,ftp這三個預設的handlers
opener = urllib2.build_opener(auth_handler)
#安裝一個opener作為全域性urlopen()使用的物件
urllib2.install_opener(opener)
res=urllib2.urlopen(top_level_url)
print res.read()
urllib2.ProxyHandler
使用代理訪問一個網站
url='http://new.nginxs.net/ip.php'
#初始化一個名為proxy代理例項
proxy = urllib2.ProxyHandler({'http':'127.0.0.1:1080'})
#這裡建立一個opener物件,這個物件可以處理http,https,ftp等協議,如果你指定了子類引數這個預設的handler將不被使用
opener = urllib2.build_opener(proxy)
#使用open方法開啟url
res = opener.open(url)
#檢視返回結果
print res.read()
Python爬蟲主要使用的是urllib模組,Python2.x版本是urllib2,很多部落格裡面的示例都是使用urllib2的,因為我使用的是Python3.3.2,所以在文件裡面沒有urllib2這個模組,import的時候會報錯,找不到該模組,應該是已經將他們整合在一起了。
在Python 3以後的版本中,urllib2這個模組已經不單獨存在(也就是說當你import urllib2時,系統提示你沒這個模組),urllib2被合併到了urllib中,叫做urllib.request 和 urllib.error 。
urllib整個模組分為urllib.request, urllib.parse, urllib.error。
例:
其中
urllib2.urlopen()變成了urllib.request.urlopen()
urllib2.Request()變成了urllib.request.Request()
urllib和urllib2模組之間的區別
在python中,urllib和urllib2不可相互替代的。
整體來說,urllib2是urllib的增強,但是urllib中有urllib2中所沒有的函式。
urllib2可以用urllib2.openurl中設定Request引數,來修改Header頭。如果你訪問一個網站,想更改User Agent(可以偽裝你的瀏覽器),你就要用urllib2.
urllib支援設定編碼的函式,urllib.urlencode,在模擬登陸的時候,經常要post編碼之後的引數,所以要想不使用第三方庫完成模擬登入,你就需要使用urllib。
urllib一般和urllib2一起搭配使用
1.urllib.urlopen(url[,data[,proxies]])
開啟一個url的方法,返回一個檔案物件,然後可以進行類似檔案物件的操作。本例試著開啟baidu
import urllib
f = urllib.urlopen('http://www.baidu.com')
firstLine = f.readline() #讀取html頁面的第一行
print firstLine
urlopen返回物件提供方法:
read() , readline() ,readlines() , fileno() , close() :這些方法的使用方式與檔案物件完全一樣
info():返回一個httplib.HTTPMessage物件,表示遠端伺服器返回的頭資訊
getcode():返回Http狀態碼。如果是http請求,200請求成功完成;404網址未找到
geturl():返回請求的url
2.urllib.urlretrieve(url[,filename[,reporthook[,data]]])
urlretrieve方法將url定位到的html檔案下載到你本地的硬碟中。如果不指定filename,則會存為臨時檔案。
urlretrieve()返回一個二元組(filename,mine_hdrs)
臨時存放:
#需要指定存放地址可用 filename = urllib.urlretrieve('http://www.baidu.com',filename='/path/baidu.html')
import urllib
filename = urllib.urlretrieve('http://www.baidu.com')
type(filename)
filename[0]
filename[1]
3.urllib.urlcleanup()
清除由於urllib.urlretrieve()所產生的快取
4.urllib.quote(url)和urllib.quote_plus(url)
將url資料獲取之後,並將其編碼,從而適用與URL字串中,使其能被列印和被web伺服器接受。
#遮蔽url中特殊的字元(包括中文),把需要編碼的字元轉化為 %xx 的形式
urllib.quote('http://www.baidu.com')
urllib.quote_plus('http://www.baidu.com')
5.urllib.unquote(url)和urllib.unquote_plus(url)
與4的函式相反
6.urllib.urlencode(query)
將URL中的鍵值對以連線符&劃分
將dict或者包含兩個元素的元組列表轉換成url引數。例如 字典{'name': 'dark-bull', 'age': 200}將被轉換為"name=dark-bull&age=200"
這裡可以與urlopen結合以實現post方法和get方法:
GET 方法:
import urllib
params=urllib.urlencode({'spam':1,'eggs':2,'bacon':0})
#params'eggs=2&bacon=0&spam=1'
f=urllib.urlopen("http://python.org/query?%s" % params)
print f.read()
import urllib
data = urllib.parse.urlencode(params).encode('utf-8')
req = urllib.request.Request(url, data)
req.add_header('Content-Type', "application/x-www-form-urlencoded")
response = urllib.request.urlopen(req)
the_page = response.read().decode('utf-8')
print(the_page)
如果不做encode,會直接報錯:POST data should be bytes or an iterable of bytes. It cannot be of type str.
如果不做decode,看到的都是assic碼
urllib模組:
urllib.urlopen(url[,data[,proxies]]) 開啟一個url的方法,返回一個檔案物件,然後可以進行類似檔案物件的操作
urlopen返回物件提供方法:
read() , readline() ,readlines() , fileno() , close() :這些方法的使用方式與檔案物件完全一樣
info():返回一個httplib.HTTPMessage物件,表示遠端伺服器返回的頭資訊
getcode():返回Http狀態碼。如果是http請求,200請求成功完成;404網址未找到
geturl():返回請求的url
urllib.urlencode() 將URL中的鍵值對以連線符&劃分,暫時不支援urldecode();注意:urlencode的引數必須是Dictionary
如:urllib.urlencode({'spam':1,'eggs':2,'bacon':0})
結果為:eggs=2&bacon=0&spam=1
urllib.quote(url)和urllib.quote_plus(url) 將url資料獲取之後,並將其編碼,從而適用與URL字串中,使其能被列印和被web伺服器接受
如:
print urllib.quote('http://www.baidu.com')
print urllib.quote_plus('http://www.baidu.com')
結果分別為:
http%3A//www.baidu.com
http%3A%2F%2Fwww.baidu.com
urllib.unquote(url)和urllib.unquote_plus(url) 與上面正好相反
urllib2模組:
直接請求一個url地址:
urllib2.urlopen(url, data=None) 通過向指定的URL發出請求來獲取資料
構造一個request物件資訊,然後傳送請求:
urllib2.Request(url,data=None,header={},origin_req_host=None) 功能是構造一個請求資訊,返回的req就是一個構造好的請求
urllib2.urlopen(url, data=None) 功能是傳送剛剛構造好的請求req,並返回一個檔案類的物件response,包括了所有的返回資訊
response.read() 可以讀取到response裡面的html
response.info() 可以讀到一些額外的響應頭資訊
主要區別:
urllib2可以接受一個Request類的例項來設定URL請求的headers,urllib僅可以接受URL。這意味著,你不可以通過urllib模組偽裝你的User Agent字串等(偽裝瀏覽器)。
urllib提供urle