小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

使用urllib

 印度阿三17 2019-07-30

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)Request

urlopen()方法可以實(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)站

爬蟲名稱 名稱 網(wǎng)站
BaiduSpider 百度 www.baidu.com
Googlebor 谷歌 www.google.com
360Spider 360搜索 www.so.com
YodaoBor 有道 www.youdao.com
ia_archiver Alexa www.alexa.cn
Scooter altavista www.altavista.com

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

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多