python爬蟲開發(fā)之urllib模塊詳細使用方法與實例全解
爬蟲所需要的功能,基本上在urllib中都能找到,學習這個標準庫,可以更加深入的理解后面更加便利的requests庫。
首先
在Pytho2.x中使用import urllib2——-對應的,在Python3.x中會使用import urllib.request,urllib.error
在Pytho2.x中使用import urllib——-對應的,在Python3.x中會使用import urllib.request,urllib.error,urllib.parse
在Pytho2.x中使用import urlparse——-對應的,在Python3.x中會使用import urllib.parse
在Pytho2.x中使用import urlopen——-對應的,在Python3.x中會使用import urllib.request.urlopen
在Pytho2.x中使用import urlencode——-對應的,在Python3.x中會使用import urllib.parse.urlencode
在Pytho2.x中使用import urllib.quote——-對應的,在Python3.x中會使用import urllib.request.quote
在Pytho2.x中使用cookielib.CookieJar——-對應的,在Python3.x中會使用http.CookieJar
在Pytho2.x中使用urllib2.Request——-對應的,在Python3.x中會使用urllib.request.Request
urllib是Python自帶的標準庫,無需安裝,直接可以用。
urllib模塊提供了如下功能:
- 網(wǎng)頁請求(urllib.request)
- URL解析(urllib.parse)
- 代理和cookie設置
- 異常處理(urllib.error)
- robots.txt解析模塊(urllib.robotparser)
urllib包中urllib.request模塊
1、urllib.request.urlopen
urlopen一般常用的有三個參數(shù),它的參數(shù)如下:
r = urllib.requeset.urlopen(url,data,timeout)
url:鏈接格式:協(xié)議://主機名:[端口]/路徑
data:附加參數(shù) 必須是字節(jié)流編碼格式的內(nèi)容(bytes類型),可通過bytes()函數(shù)轉(zhuǎn)化,如果要傳遞這個參數(shù),請求方式就不再是GET方式請求,而是POST方式
timeout: 超時 單位為秒
get請求
import urllib r = urllib.urlopen('//www.dbjr.com.cn/') datatLine = r.readline() #讀取html頁面的第一行 data=file.read() #讀取全部 f=open("./1.html","wb") # 網(wǎng)頁保存在本地 f.write(data) f.close()
urlopen返回對象提供方法:
read() , readline() ,readlines() , fileno() , close() :這些方法的使用方式與文件對象完全一樣 info():返回一個httplib.HTTPMessage對象,表示遠程服務器返回的頭信息 getcode():返回Http狀態(tài)碼。如果是http請求,200請求成功完成;404網(wǎng)址未找到 geturl():返回請求的url
urllib.quote(url)和urllib.quote_plus(url),對關(guān)鍵字進行編碼可使得urlopen能夠識別
POST請求
import urllib.request import urllib.parse url = 'https://passport.jb51.net/user/signin?' post = { 'username': 'xxx', 'password': 'xxxx' } postdata = urllib.parse.urlencode(post).encode('utf-8') req = urllib.request.Request(url, postdata) r = urllib.request.urlopen(req)
我們在進行注冊、登錄等操作時,會通過POST表單傳遞信息
這時,我們需要分析頁面結(jié)構(gòu),構(gòu)建表單數(shù)據(jù)post,使用urlencode()進行編碼處理,返回字符串,再指定'utf-8'的編碼格式,這是因為POSTdata只能是bytes或者file object。最后通過Request()對象傳遞postdata,使用urlopen()發(fā)送請求。
2、urllib.request.Request
urlopen()方法可以實現(xiàn)最基本請求的發(fā)起,但這幾個簡單的參數(shù)并不足以 構(gòu)建一個完整的請求,如果請求中需要加入headers(請求頭)等信息模擬瀏覽器,我們就可以利用更強大的Request類來構(gòu)建一個請求。
import urllib.request import urllib.parse url = 'https://passport.jb51.net/user/signin?' post = { 'username': 'xxx', 'password': 'xxxx' } postdata = urllib.parse.urlencode(post).encode('utf-8') req = urllib.request.Request(url, postdata) r = urllib.request.urlopen(req)
3、urllib.request.BaseHandler
在上面的過程中,我們雖然可以構(gòu)造Request ,但是一些更高級的操作,比如 Cookies處理,代理該怎樣來設置?
接下來就需要更強大的工具 Handler 登場了 基本的urlopen()函數(shù)不支持驗證、cookie、代理或其他HTTP高級功能。要支持這些功能,必須使用build_opener()函數(shù)來創(chuàng)建自己的自定義opener對象。
首先介紹下 urllib.request.BaseHandler ,它是所有其他 Handler 的父類,它提供了最基本的 Handler 的方法。
HTTPDefaultErrorHandler 用于處理HTTP響應錯誤,錯誤都會拋出 HTTPError 類型的異常。
HTTPRedirectHandler 用于處理重定向
HTTPCookieProcessor 用于處理 Cookie 。
ProxyHandler 用于設置代理,默認代理為空。
HTTPPasswordMgr用于管理密碼,它維護了用戶名密碼的表。
HTTPBasicAuthHandler 用于管理認證,如果一個鏈接打開時需要認證,那么可以用它來解決認證問題。
代理服務器設置
def use_proxy(proxy_addr,url): import urllib.request #構(gòu)建代理 proxy=urllib.request.ProxyHandler({'http':proxy_addr}) # 構(gòu)建opener對象 opener=urllib.request.build_opener(proxy,urllib.request.HTTPHandler) # 安裝到全局 # urllib.request.install_opener(opener) # data=urllib.request.urlopen(url).read().decode('utf8') 以全局方式打開 data=opener.open(url) # 直接用句柄方式打開 return data proxy_addr='61.163.39.70:9999' data=use_proxy(proxy_addr,'//www.dbjr.com.cn') print(len(data)) ## 異常處理以及日輸出
opener通常是build_opener()創(chuàng)建的opener對象。
install_opener(opener) 安裝opener作為urlopen()使用的全局URL opener
cookie的使用
獲取Cookie保存到變量
import http.cookiejar, urllib.request #使用http.cookiejar.CookieJar()創(chuàng)建CookieJar對象 cookie = http.cookiejar.CookieJar() handler = urllib.request.HTTPCookieProcessor(cookie) #使用HTTPCookieProcessor創(chuàng)建cookie處理器,并以其為參數(shù)構(gòu)建opener對象 opener = urllib.request.build_opener(handler) #將opener安裝為全局 urllib.request.install_opener(opener) response = urllib.request.urlopen('//www.dbjr.com.cn') #response = opener.open('//www.dbjr.com.cn') for item in cookie: print 'Name = '+item.name print 'Value = '+item.value
首先我們必須聲明一個 CookieJar 對象,接下來我們就需要利用 HTTPCookieProcessor 來構(gòu)建一個 handler ,最后利用 build_opener 方法構(gòu)建出 opener ,執(zhí)行 open() 即可。 最后循環(huán)輸出cookiejar
獲取Cookie保存到本地
import cookielib import urllib #設置保存cookie的文件,同級目錄下的cookie.txt filename = 'cookie.txt' #聲明一個MozillaCookieJar對象實例來保存cookie,之后寫入文件 cookie = cookielib.MozillaCookieJar(filename) #利用urllib庫的HTTPCookieProcessor對象來創(chuàng)建cookie處理器 handler = urllib.request.HTTPCookieProcessor(cookie) #通過handler來構(gòu)建opener opener = urllib.request.build_opener(handler) #創(chuàng)建一個請求,原理同urllib2的urlopen response = opener.open("http://www.dbjr.com.cn") #保存cookie到文件 cookie.save(ignore_discard=True, ignore_expires=True)
異常處理
異常處理結(jié)構(gòu)如下
try: # 要執(zhí)行的代碼 print(...) except: #try代碼塊里的代碼如果拋出異常了,該執(zhí)行什么內(nèi)容 print(...) else: #try代碼塊里的代碼如果沒有跑出異常,就執(zhí)行這里 print(...) finally: #不管如何,finally里的代碼,是總會執(zhí)行的 print(...)
URLerror產(chǎn)生原因:
1、網(wǎng)絡未連接(即不能上網(wǎng))
from urllib import request, error try: r=request.urlopen('//www.dbjr.com.cn') except error.URLError as e: print(e.reason)
2、訪問頁面不存(HTTPError)
客戶端向服務器發(fā)送請求,如果成功地獲得請求的資源,則返回的狀態(tài)碼為200,表示響應成功。如果請求的資源不存在, 則通常返回404錯誤。
from urllib imort request, error try: response = request.urlopen('//www.dbjr.com.cn') except error.HTTPError as e: print(e.reason, e.code, e.headers, sep='\n') else: print("Request Successfully') # 加入 hasattr屬性提前對屬性,進行判斷原因 from urllib import request,error try: response=request.urlopen('http://blog.jb51.net') except error.HTTPError as e: if hasattr(e,'code'): print('the server couldn\'t fulfill the request') print('Error code:',e.code) elif hasattr(e,'reason'): print('we failed to reach a server') print('Reason:',e.reason) else: print('no exception was raised') # everything is ok
下面為大家列出幾個urllib模塊很有代表性的實例
1、引入urllib模塊
import urllib.request response = urllib.request.urlopen('http://jb51.net/') html = response.read()
2、使用 Request
import urllib.request req = urllib.request.Request('http://jb51.net/') response = urllib.request.urlopen(req) the_page = response.read()
3、發(fā)送數(shù)據(jù)
#! /usr/bin/env python3 import urllib.parse import urllib.request url = 'http://localhost/login.php' user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' values = { 'act' : 'login', 'login[email]' : 'yzhang@i9i8.com', 'login[password]' : '123456' } data = urllib.parse.urlencode(values) req = urllib.request.Request(url, data) req.add_header('Referer', '//www.dbjr.com.cn/') response = urllib.request.urlopen(req) the_page = response.read() print(the_page.decode("utf8"))
4、發(fā)送數(shù)據(jù)和header
#! /usr/bin/env python3 import urllib.parse import urllib.request url = 'http://localhost/login.php' user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' values = { 'act' : 'login', 'login[email]' : 'yzhang@i9i8.com', 'login[password]' : '123456' } headers = { 'User-Agent' : user_agent } data = urllib.parse.urlencode(values) req = urllib.request.Request(url, data, headers) response = urllib.request.urlopen(req) the_page = response.read() print(the_page.decode("utf8"))
5、http 錯誤
#! /usr/bin/env python3 import urllib.request req = urllib.request.Request('//www.dbjr.com.cn ') try: urllib.request.urlopen(req) except urllib.error.HTTPError as e: print(e.code) print(e.read().decode("utf8"))
6、異常處理
#! /usr/bin/env python3 from urllib.request import Request, urlopen from urllib.error import URLError, HTTPError req = Request("http://www.dbjr.com.cn /") try: response = urlopen(req) except HTTPError as e: print('The server couldn't fulfill the request.') print('Error code: ', e.code) except URLError as e: print('We failed to reach a server.') print('Reason: ', e.reason) else: print("good!") print(response.read().decode("utf8"))
7、異常處理
from urllib.request import Request, urlopen from urllib.error import URLError req = Request("http://www.dbjr.com.cn /") try: response = urlopen(req) except URLError as 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: print("good!") print(response.read().decode("utf8"))
8、HTTP 認證
#! /usr/bin/env python3 import urllib.request # create a password manager password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm() # Add the username and password. # If we knew the realm, we could use it instead of None. top_level_url = "http://www.dbjr.com.cn /" password_mgr.add_password(None, top_level_url, 'rekfan', 'xxxxxx') handler = urllib.request.HTTPBasicAuthHandler(password_mgr) # create "opener" (OpenerDirector instance) opener = urllib.request.build_opener(handler) # use the opener to fetch a URL a_url = "http://www.dbjr.com.cn /" x = opener.open(a_url) print(x.read()) # Install the opener. # Now all calls to urllib.request.urlopen use our opener. urllib.request.install_opener(opener) a = urllib.request.urlopen(a_url).read().decode('utf8') print(a)
9、使用代理
#! /usr/bin/env python3 import urllib.request proxy_support = urllib.request.ProxyHandler({'sock5': 'localhost:1080'}) opener = urllib.request.build_opener(proxy_support) urllib.request.install_opener(opener) a = urllib.request.urlopen("http://www.dbjr.com.cn ").read().decode("utf8") print(a)
10、超時
#! /usr/bin/env python3 import socket import urllib.request # timeout in seconds timeout = 2 socket.setdefaulttimeout(timeout) # this call to urllib.request.urlopen now uses the default timeout # we have set in the socket module req = urllib.request.Request('//www.dbjr.com.cn /') a = urllib.request.urlopen(req).read() print(a)
11.自己創(chuàng)建build_opener
header=[('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36')] #創(chuàng)建opener對象 opener=urllib.request.build_opener() opener.addheaders=header #設置opener對象作為urlopen()使用的全局opener urllib.request.install_opener(opener) response =urllib.request.urlopen('//www.dbjr.com.cn/') buff = response.read() html = buff .decode("utf8") response.close() print(the_page)
12.urlib.resquest.urlretrieve遠程下載
header=[('User-Agent','Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36')] #創(chuàng)建opener對象 opener=urllib.request.build_opener() opener.addheaders=header #設置opener對象作為urlopen()使用的全局opener urllib.request.install_opener(opener) #下載文件到當前文件夾 urllib.request.urlretrieve('//www.dbjr.com.cn/','baidu.html') #清除urlretrieve產(chǎn)生的緩存 urlib.resquest.urlcleanup()
13.post請求
import urllib.request import urllib.parse url='//www.dbjr.com.cn/mypost/' #將數(shù)據(jù)使用urlencode編碼處理后,使用encode()設置為utf-8編碼 postdata=urllib.parse.urlencode({name:'測試名',pass:"123456"}).encode('utf-8') #urllib.request.quote()接受字符串, #urllib.parse.urlencode()接受字典或者列表中的二元組[(a,b),(c,d)],將URL中的鍵值對以連接符&劃分 req=urllib.request.Request(url,postdata) #urllib.request.Request(url, data=None, header={}, origin_req_host=None, unverifiable=False, #method=None) #url:包含URL的字符串。 #data:http request中使用,如果指定,則發(fā)送POST而不是GET請求。 #header:是一個字典。 #后兩個參數(shù)與第三方cookie有關(guān)。 req.add_header('user-agent','User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/ 537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36 SE 2.X MetaSr 1.0') data=urllib.request.urlopen(req).read() //urlopen()的data參數(shù)默認為None,當data參數(shù)不為空的時候,urlopen()提交方式為Post。
14.cookie的使用
1.獲取Cookie保存到變量
import urllib.request import http.cookie # 聲明一個CookieJar對象實例來保存cookie cookie = cookielib.CookieJar() # 利用urllib庫的HTTPCookieProcessor對象來創(chuàng)建cookie處理器 handler = urllib.request.HTTPCookieProcessor(cookie) # 通過handler來構(gòu)建opener opener = urllib.request.build_opener(handler) # 此處的open方法同urllib.request的urlopen方法,也可以傳入request urllib.request.install_opener(opener) #使用opener或者urlretrieve方法來獲取需要的網(wǎng)站cookie urllib.request.urlretrieve('//www.dbjr.com.cn/','baidu.html') # data=urllib.request.urlopen('//www.dbjr.com.cn/')
2.保存cookies到文件
import http.cookie import urllib.request # 設置保存cookie的文件,同級目錄下的cookie.txt filename = 'cookie.txt' # 聲明一個MozillaCookieJar對象實例來保存cookie,之后寫入文件 cookie = http.cookie.MozillaCookieJar(filename) # 利用urllib庫的HTTPCookieProcessor對象來創(chuàng)建cookie處理器 handler = urllib.request.HTTPCookieProcessor(cookie) # 通過handler來構(gòu)建opener opener = urllib.request.build_opener(handler) # 創(chuàng)建一個請求,原理同urllib的urlopen response = opener.open("http://www.dbjr.com.cn") # 保存cookie到文件 cookie.save(ignore_discard=True, ignore_expires=True)
3.從文件中獲取cookies并訪問
import http.cookielib import urllib.request # 創(chuàng)建MozillaCookieJar實例對象 cookie = http.cookie.MozillaCookieJar() # 從文件中讀取cookie內(nèi)容到變量 cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True) # 創(chuàng)建請求的request req = urllib.Request("http://www.dbjr.com.cn") # 利用urllib的build_opener方法創(chuàng)建一個opener opener = urllib.build_opener(urllib.request.HTTPCookieProcessor(cookie)) response = opener.open(req) print (response.read())
15.代理服務器設置
import socket #設置Socket連接超時時間,同時決定了urlopen的超時時間 socket.setdefaulttimeout(1) import urllib.request #代理服務器信息,http代理使用地址 startime = time.time() #設置http和https代理 proxy=request.ProxyHandler({'https':'175.155.25.91:808','http':'175.155.25.91:808'}) opener=request.build_opener(proxy) opener.addheaders=[('User-Agent','Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0'), # ("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"), # ("Accept-Language", "zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3"), # ("Accept-Encoding","gzip, deflate, br"), # ("Connection","keep-alive"), # ("Pragma","no-cache"), # ("Cache-Control","no-cache") ] request.install_opener(opener) # data = request.urlopen('http://www.dbjr.com.cn/find-ip-address').read() data = request.urlopen( 'http://www.ipip.net/' ).read().decode('utf-8') # data=gzip.decompress(data).decode('utf-8','ignore') endtime = time.time() delay = endtime-startime print(data)
有時在urlopen的data數(shù)據(jù)直接decode(‘utf-8')會失敗,必須要使用gzip.decompress(‘utf-8','ignore')才能打開,猜測應該是header的問題,換一個有時會好
本文主要講解了python爬蟲模塊urllib詳細使用方法與實例全解,更多關(guān)于python爬蟲模塊urllib詳細使用方法與實例請查看下面的相關(guān)鏈接
相關(guān)文章
python獲取linux和windows系統(tǒng)指定接口的IP地址的步驟及代碼
這篇文章主要介紹了python獲取linux和windows系統(tǒng)指定接口的IP地址,本文分步驟通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-05-05python實現(xiàn)啟動一個外部程序,并且不阻塞當前進程
這篇文章主要介紹了python實現(xiàn)啟動一個外部程序,并且不阻塞當前進程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-12-12python [:3] 實現(xiàn)提取數(shù)組中的數(shù)
今天小編就為大家分享一篇python [:3] 實現(xiàn)提取數(shù)組中的數(shù),具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-11-11