|
urllib庫是Python內(nèi)置的HTTP請(qǐng)求庫,包含4個(gè)模塊 1)request:它是最基本的HTTP請(qǐng)求模板,可以用來模擬發(fā)送請(qǐng)求 2)error:異常處理模塊,如果出現(xiàn)請(qǐng)求錯(cuò)誤,我們可以捕獲這些異常,然后可以進(jìn)行重試或其他操作來保證程序不會(huì)意外終止 3)parse:一個(gè)工具模塊,提供許多URL處理方法,如拆分,解析合并等 4)robotparser:主要用來識(shí)別網(wǎng)站的robots.txt文件,然后判斷哪些網(wǎng)站可以爬,哪些網(wǎng)站不可以爬 一.發(fā)送請(qǐng)求使用urllib的request模塊,可以方便地實(shí)現(xiàn)請(qǐng)求的發(fā)送并得到響應(yīng) 1)urlopen()
urlopen()方法除了第一個(gè)參數(shù)可以傳遞URL外,還可以傳遞其他內(nèi)容,比如data,timeout等 A.data參數(shù) data參數(shù)是可選的。如果要添加該參數(shù),并且如果它是字節(jié)流編碼格式的內(nèi)容,即bytes類型,則需要通過bytes()方法轉(zhuǎn)化。如果傳遞了這個(gè)參數(shù),則它的請(qǐng)求方式不再是GET方式,而是POST方式 B.timeout參數(shù) timeout參數(shù)用于設(shè)置超時(shí)時(shí)間,單位為秒,如果請(qǐng)求超出了設(shè)置時(shí)間,還沒有得到響應(yīng),就會(huì)拋出異常,如果不知道該參數(shù),就會(huì)使用全局默認(rèn)時(shí)間,它支持HTTP,HTTPS,F(xiàn)TP請(qǐng)求 C.其他參數(shù) context參數(shù),它是必須是ssl.SSLContext類型用來指定SSL設(shè)置 此外,cafile和capath這兩個(gè)參數(shù)用來指定CA證書和他的路徑,這個(gè)在請(qǐng)求HTTPS鏈接時(shí)有用 ?2)Requesturlopen()方法可以實(shí)現(xiàn)最基本請(qǐng)求的發(fā)起,但其簡(jiǎn)單的參數(shù)并不足以構(gòu)建一個(gè)完整的請(qǐng)求,如果需要在請(qǐng)求中/加入Headers等信息,則需要利用強(qiáng)大的Request來構(gòu)建
Request參數(shù)構(gòu)造方法
1)第一個(gè)參數(shù)url用于請(qǐng)求URL,這是必傳參數(shù),其他都是可選參數(shù) 2)第二個(gè)參數(shù)data如果要傳,必須傳bytes(字節(jié)流)類型的,如果它是字典,可以先用urllib。parse模塊里的urlencode()編碼 3)第三個(gè)參數(shù)headers是一個(gè)字典,它就是請(qǐng)求頭,可以在構(gòu)造請(qǐng)求時(shí)通過headers參數(shù)直接構(gòu)造,也可以通過調(diào)用請(qǐng)求實(shí)例的add_header()方法調(diào)用 4)第四個(gè)參數(shù)origin_req_host指的是請(qǐng)求方的host名稱或者IP地址 5)第五個(gè)參數(shù)unverifiable表示這個(gè)請(qǐng)求是否是無法驗(yàn)證的,默認(rèn)為false,意思是用戶沒有足夠的權(quán)限來選擇接收這個(gè)請(qǐng)求的結(jié)果 6)第六個(gè)參數(shù)method是一個(gè)字符串,用來指示請(qǐng)求使用的方法,如GET,POST和PUT等 from urllib import request,parse
url="http:///post"
headers={
'User-Agent':'Mozilla/4.0(compatible;MSIE 5.5;Windows NT)',
'Host':''
}
dict={
'name':'Germey'
}
data=bytes(parse.urlencode(dict),encoding='utf-8')
req=request.Request(url=url,data=data,headers=headers,method='POST')
response=request.urlopen(req)
print(response.read().decode("utf-8"))
3)高級(jí)用法對(duì)于一些高級(jí)操作,如Cookies處理,代理設(shè)置等,就要用到Handler,可以把它理解為各種處理器,有專門處理登錄驗(yàn)證的,有處理Cookies的,有處理代理設(shè)置的 urllib.request模塊里的BaseHandler類是所有其他Handler的父類,它提供了最基本的方法 下面是各種Handler子類繼承這個(gè)BaseHandler類 1)HTTPDefaultErroeHandler: 用于處理HTTP響應(yīng)錯(cuò)誤,錯(cuò)誤都會(huì)拋出HTTPError類型的異常 2)HTTPRedirectHandler: 用于處理重定向 3)HTTPCookieProcessor: 用于處理Cookies 4)ProxyHandler:用于設(shè)置代理,默認(rèn)代理為空 5)HTTPPasswordMgr:用于管理密碼,它維護(hù)了用戶名和密碼的表 6)HTTPBasicAuthHandler:用于管理認(rèn)證,如果一個(gè)鏈接打開時(shí)需要認(rèn)證,那么可以用它來解決認(rèn)證問題 另外一個(gè)比較重要的類是OpenerDirector,我們可以稱為Opener,之前用過的urlopen()實(shí)際上就是urllib為我們提供的一個(gè)Opener 我們需要實(shí)現(xiàn)更高級(jí)的功能,所以需要深入一層進(jìn)行配置,使用更底層的實(shí)例來完成操作,所以就用到Opener,Opener可以使用open()方法,返回類型和urlopen()一樣 利用Hanler來構(gòu)建Opener 用法: A.驗(yàn)證 有些網(wǎng)站需要輸入用戶名和密碼,驗(yàn)證成功后才能查看頁面,要請(qǐng)求這樣的頁面,需要借助HTTPBasicAuthHandler就可以完成 from urllib.request import HTTPPasswordWithDefaultRealm,HTTPBasicAuthHandler,build_opener
from urllib.error import URLError
username='username'
password='password'
url='http://localhost:5000/'
p=HTTPPasswordWithDefaultRealm()
p.add_passsword(None,url,username,password)
auth_handler=HTTPBasicAuthHandler(p)
opener=built_opener(auth_handler)
try:
result=opener.open(url)
html=result.read().decode('utf-8')
print(html)
except URLError as e:
print(e.reason)
B.代理 在做爬蟲時(shí),如果要添加代理,可以這樣做 from urllib.error import URLError
from urllib.request import ProxyHandler,build_opener
proxy_handler =ProxyHandler({
'http':'http://127.0.0.1:9743',
'https':'https://127.0.0.1:9743'
})
opener=build_opener(proxy_handler)
try:
response=opener.open('https://www.baidu.com')
print(resposne.read().decode("urtf-8"))
except URLError as e:
print(e.reason)
使用ProxyHandler,其參數(shù)是一個(gè)字典,鍵名是協(xié)議類型(如HTTP或HTTTPS),鍵值是代理鏈接,可以添加多個(gè)代理 C.Cookies Cookies的處理就需要相關(guān)的Handler from urllib.request import HTTPCookieProcessor,build_opener
import http.cookiejar
cookie=http.cookiejar.CookieJar()
handler=HTTPCookieProcessor(cookie)
opener=build_opener(handler)
response=opener.open("https://www.baidu.com")
for i in cookie:
print(i.name '=' i.value)
這樣可以看到每條Cookie的名稱和值 將cookie以文本形式保存代碼如下 import http.cookiejar,urllib.request
filename='Cookies.text'
cookie=http.cookiejar.MozillaCookieJar(filename)
handler=urllib.request.HTTPCookieProcessor(cookie)
opener=urllib.request.build_opener(handler)
response=opener.open("https://www.baidu.com")
cookie.save(ignore_discard=True,ignore_expires=True)
MozillaCookieJar才生成文件時(shí)會(huì)用到,時(shí)CookieJar的子類??梢杂脕硖幚鞢ookies和文件相關(guān)的事件,比如讀取和保存Cookies,可以將Cookies保存成Mozilla型瀏覽器的Cookies格式 LWPCookieJar也可以讀取和保存Cookies,但是保存的格式和MozillaCookieJar的不一樣,它會(huì)保存成libwww-perl(LWP)格式的Cookies文件 從文件中讀?。?/p> import http.cookiejar,urllib.request
cookie=http.cookiejar.MozillaCookieJar()
cookie.load('Cookies.txt',ignore_discard=True,ignore_expires=True)
handler=urllib.request.HTTPCookieProcessor(cookie)
opener=urllib.request.build_opener(handler)
response=opener.open("https://www.baidu.com")
print(response.read().decode('utf-8'))
?二.處理異常urllib的error模塊定義了由request模塊產(chǎn)生的異常。如果出現(xiàn)了問題,request模塊便會(huì)拋出error中定義的異常 A.URLError URLError類來自u(píng)rllib庫的error模塊,它繼承自O(shè)SError類,是error異常模塊的基類,有request模塊生的異常都可以通過這個(gè)類來處理 from urllib import request,error
try:
response=request.urlopen("https://www.")
except error.URLError as e:
print(e.reason)
B.HTTPError 它是URLError的子類,專門用來處理HTTP請(qǐng)求錯(cuò)誤,比如認(rèn)證請(qǐng)求失敗,它有三個(gè)屬性 1)code:返回HTTP狀態(tài)碼,比如404表示網(wǎng)頁不存在,500表示服務(wù)器內(nèi)部錯(cuò)誤 2)reason:同父類一樣,用于返回錯(cuò)誤的原因 3)headers:返回請(qǐng)求頭 from urllib import request,error
try:
response=request.urlopen("https:///index.htm")
except error.HTTPError as e:
print(e.code,e.reason,e.headers)
?三.解析鏈接urllib庫還提供了parse模塊,它定義了處理URL的標(biāo)準(zhǔn)接口,例如實(shí)現(xiàn)URL各部分的抽取,合并以及鏈接轉(zhuǎn)換 1)urlparse該方法可以實(shí)現(xiàn)URL的識(shí)別和分段 from urllib.parse import urlparse
result=urlparse("https://www.dengwenxiong/index.html;user?id=5#comment")
print(result)
ParseResult(scheme='https', netloc='www.dengwenxiong', path='/index.html', params='user', query='id=5', fragment='comment') 其將url分為6部分scheme表示協(xié)議,netloc表示域名,path表示訪問路徑,params表示參數(shù),query表示查詢條件,fragment表示錨點(diǎn),用于直接定位頁面內(nèi)部的下拉位置 urlparse()有三個(gè)參數(shù):urlstring,scheme和allow_fragments uslstring是必填項(xiàng),即待解析的URL scheme:它是默認(rèn)的協(xié)議,假如鏈接沒有協(xié)議,會(huì)將這個(gè)作為默認(rèn)的協(xié)議 allow_fragments:即是否忽略fragment,如果它被設(shè)置為false,fragment部分被忽略,它會(huì)被解析成path,parameters或者query的一部分,而fragment部分為空 2)urlunparse它接受的參數(shù)是一個(gè)可迭代對(duì)象,但是它的長(zhǎng)度必須是6,否則會(huì)拋出參數(shù)數(shù)量不足或者過多的問題 from urllib.parse import urlunparse
data=('https','www.baidu.com','index.html','user','a=6','comment')
print(urlunparse(data))
3)urlsplit()這個(gè)方法和urlparse()方法非常相似,只不過它不在單獨(dú)解析params這一部分,只返回5個(gè)結(jié)果,params會(huì)合并到path中,可以用屬性獲取值,也可以用索引來獲取 4)urlunsplit()與urlunparse()類似,也是將鏈接各個(gè)部分組合成完整鏈接的方法,傳入的參數(shù)也是一個(gè)可迭代對(duì)象,唯一的區(qū)別是長(zhǎng)度必須為5 5)urljoin()生成鏈接除了上面兩個(gè)方法,還有就是urljoin()方法,可以提供一個(gè)base_url(基礎(chǔ)鏈接)作為第一個(gè)參數(shù),將新的鏈接作為第二個(gè)參數(shù),該方法會(huì)分析base_url的scheme,netloc和path這三個(gè)內(nèi)容并對(duì)新鏈接缺失的部分進(jìn)行補(bǔ)充 base_url提供三項(xiàng)內(nèi)容scheme,netloc和path,如果這3項(xiàng)在新的鏈接里不存在,就予以補(bǔ)充,如果新的鏈接存在,就使用新的鏈接的部分,而base_url中的params,query和fragment是不起作用的 from urllib.parse import urljoin
print(urljoin('http://www.baidu.com','FAQ.html'))
6)urlencode()它在構(gòu)造get請(qǐng)求參數(shù)的時(shí)候非常有用 from urllib.parse import urlencode
params={
'name':'dwx',
'age':22
}
base_url='http://www.baidu.com?'
url=base_url urlencode(params)
print(url)
?7)parse_qs()有了序列化就要有反序列化,如果有一串GET請(qǐng)求參數(shù),利用parse_qs()方法能將其轉(zhuǎn)回字典 from urllib.parse import parse_qs query="name=dengwenxiong&age=22" print(parse_qs(query)) 8)parse_qsl()它用于將參數(shù)轉(zhuǎn)化為元組組成的列表 9)quote()該方法可以將內(nèi)容轉(zhuǎn)化為URL格式 from urllib.parse import quote key="鄧文雄" url="http://www.baidu.com/s?wd=" quote(key) print(url) 10)unquote()可以對(duì)URL進(jìn)行解碼 from urllib.parse import unquote key="鄧文雄" print(unquote(key)) ?三.分析Robots協(xié)議利用urllib的robotparser模塊,我們可以實(shí)現(xiàn)網(wǎng)站Robots協(xié)議的分析 1)Robots協(xié)議Robots協(xié)議也稱為爬蟲協(xié)議,機(jī)器人協(xié)議,全名為網(wǎng)絡(luò)爬蟲排除標(biāo)準(zhǔn)(Robots Exclusion Protocol),用來告訴爬蟲和搜索引擎哪些頁面可以抓取,哪些頁面不可抓取。它通常是一個(gè)叫作robots.txt的文本文件,一般放在網(wǎng)站的根目錄下。 當(dāng)搜索爬蟲訪問一個(gè)站點(diǎn)時(shí),它會(huì)首先檢查這。個(gè)站點(diǎn)根目錄下是否存在robots.txt文件,如果存在,搜索爬蟲會(huì)根據(jù)其中定義的爬取范圍來爬取,如果沒有找到這個(gè)文件,搜索爬蟲便會(huì)訪問所以可直接訪問的頁面 下面是一個(gè)robot.txt的樣例 A.對(duì)所有搜索爬蟲只允許爬取public目錄 User-agent:* Disallow:/ Allow:/public/ User-agent描述了搜索爬蟲的名稱,這里設(shè)置為*則代表該協(xié)議對(duì)任何爬取爬蟲有效 Disallow指定了不允許抓取的目錄,設(shè)置為/則代表不允許抓取所有頁面 Allow一般和Disallow一起使用,一般不會(huì)單獨(dú)使用,用來排除某些限制,這里設(shè)置為/public/則表示所有頁面不允許抓取,但可以抓取public目錄 B.禁止所有爬蟲訪問任何目錄 User-agent:* Disallow:/ C.允許所有爬蟲訪問任何目錄 User-agent:* Disallow: D.禁止所有爬蟲訪問網(wǎng)站某些目錄 User-agent:* Disallow:/private/ Disallow:/tmp/ E.只允許某一個(gè)爬蟲訪問 User-agent:WebCrawler Disallow: User-agent:* Disallow:/ 2)爬蟲名稱一些常見搜索爬蟲的名稱即其對(duì)應(yīng)的網(wǎng)站
3)robotparser可以用robotparser模塊來解析robots.txt;該模塊提供了一個(gè)類RobotFileParser,它可以根據(jù)某網(wǎng)站的robots.txt文件來判斷一個(gè)爬取爬蟲是否有權(quán)限來爬取這個(gè)網(wǎng)頁;這個(gè)類用起來非常簡(jiǎn)單,只需要在構(gòu)造方法里傳入robots.txt的鏈接即可,其聲明如下: urllib.robotparser.RobotFileParser(url=' ') 也可以在聲明時(shí)不傳入,默認(rèn)為空,使用set_url()方法設(shè)置也行; 這個(gè)類常用的幾個(gè)方法: 1)set_url():用來設(shè)置robots.txt文件的鏈接。如果在創(chuàng)建RobotFileParser對(duì)象時(shí)傳入了鏈接,那么就不需要再使用這個(gè)方法設(shè)置了 2)read():讀取robots.txt文件并進(jìn)行分析,這個(gè)方法執(zhí)行一個(gè)讀取和分析操作,如果不調(diào)用這個(gè)方法,接下來的判斷都會(huì)為false,所以一定要調(diào)用這個(gè)方法,這個(gè)方法不返回任何內(nèi)容,但是執(zhí)行了讀取操作 3)parse():用來解析robots.txt文件,傳入的參數(shù)是robots.txt某些行的內(nèi)容,它會(huì)按照robots.txt的語法規(guī)則來分析這些內(nèi)容 4)can_fetch():該方法傳入兩個(gè)參數(shù),第一個(gè)是User-agent,第二個(gè)是要抓取的URL。返回的內(nèi)容是該搜索引擎是否可以抓取這個(gè)URL,返回的結(jié)果是True或False 5)mtime():返回的是上次抓取和分析robots.txt的時(shí)間,這對(duì)于長(zhǎng)時(shí)間分析和抓取的搜索爬蟲是很有必要的,你可能需要定期檢查來抓取最新的robots.txt 6)modified():它對(duì)長(zhǎng)時(shí)間分析和抓取的搜索爬蟲很有幫助,將當(dāng)前時(shí)間設(shè)置為上次抓取和分析robots.txt的時(shí)間 from urllib.robotparser import RobotFileParser
rp=RobotFileParser()
rp.set_url('http://www.jianshu.com/robots.txt')
rp.read()#也可用parse()讀取和分析rp.parse(urlopen('http://www.jianshu.com/robots.txt').read().decode('utf-8').split('\n'))
print(rp.can_fetch('*','http://www.jianshu.com/'))
? 來源:https://www./content-4-369601.html |
|
|