爬蟲小白:02-urllib的使用

urllib的使用

一贾虽、request模塊

http://httpbin.org 是github的http測(cè)試的接口省骂。httpbin.org 這個(gè)網(wǎng)站能測(cè)試 HTTP 請(qǐng)求和響應(yīng)的各種信息器联,比如 cookie蕉世、ip、headers 和登錄驗(yàn)證等狭姨,且支持 GET宰啦、POST 等多種方法,對(duì) web 開(kāi)發(fā)和測(cè)試很有幫助饼拍。

導(dǎo)入模塊:
1赡模、import urllib
使用:urllib.request.
但這樣會(huì)報(bào)錯(cuò): AttributeError: module 'urllib' has no attribute 'request'
原因:在python3中request被作為一個(gè)模塊,而不是方法师抄。
解決方法:將request作為一個(gè)模塊漓柑,如import urllib.request。

2叨吮、from urllib import request
requset.
?
1辆布、urlopen()方法:是一個(gè)簡(jiǎn)單發(fā)送網(wǎng)絡(luò)請(qǐng)求的方法。它接收一個(gè)字符串格式的 url 茶鉴,它會(huì)向傳入的 url發(fā)送網(wǎng)絡(luò)請(qǐng)求锋玲,然后返回結(jié)果。
參數(shù):
(1)url='' #字符串格式
例:
import urllib
response =urllib.request.urlopen(url='http://httpbin.org/get')

(2)data:是可選的涵叮,傳入它則會(huì)發(fā)起POST請(qǐng)求惭蹂,否則默認(rèn)會(huì)發(fā)送get請(qǐng)求伞插。data參數(shù)是字節(jié) 類型、或者類文件對(duì)象或可迭代對(duì)象盾碗。
import urllib import request
response = request.urlopen(url='http://httpbin.org/post',
data=b'username=wsq&password=123')

用data就是post請(qǐng)求,字節(jié)類型,用b''來(lái)轉(zhuǎn)換成字節(jié),且data中的數(shù)據(jù)會(huì)作為表單中的數(shù)據(jù)蜂怎。

(3)timeout:設(shè)置超時(shí)時(shí)間,以秒為單位置尔。如果請(qǐng)求超過(guò)設(shè)置時(shí)間杠步,則拋出異常;若沒(méi)有指定 則用系統(tǒng)默認(rèn)設(shè)置榜轿。timeout參數(shù)只對(duì) http幽歼、https以及ftp連接起作用。
報(bào)錯(cuò)會(huì)出現(xiàn):urllib.error.URLError: <urlopen error timed out>
from urllib
response =urllib.request.urlopen(url='http://www.baidu.com',
timeout=0.1)
2谬盐、Request類:
解釋:利用urlopen()可以發(fā)起最基本的請(qǐng)求甸私,但這幾個(gè)參數(shù)不足以構(gòu)件一個(gè)完整的請(qǐng)求,可以利用 Request對(duì)象來(lái)構(gòu)建更加完整的請(qǐng)求飞傀。
(1) 請(qǐng)求頭添加:
from urllib import request
headers={
'User-Agent':"Mozilla/5.0 (Windows NT 10.0; Win64; x64rv:73.0) Gecko/20100101 Firefox/73.0"
} #注意:一定是字典形式皇型。
req = request.Request(url='http://www.baidu.com',headers = headers)

reponse = request.urlopen(req)
Referer:這個(gè)涉及防盜鏈技術(shù),假如爬取一個(gè)圖片出現(xiàn)403砸烦,在請(qǐng)求頭里添加上它弃鸦,大多數(shù)都 可以解決。

(2) 操作Cookie幢痘。(但不會(huì)用它操作唬格,日后常用request)
(3) 設(shè)置代理:自己寫個(gè)代理庫(kù)。(間接請(qǐng)求颜说,保護(hù)自己的IP地址)
(4) 驗(yàn)證:
?</pre>

3购岗、Response對(duì)象:
urllib庫(kù)中的類或者方法,在發(fā)送網(wǎng)絡(luò)請(qǐng)求后门粪,都會(huì)返回一個(gè)urllib.response的對(duì)象(例如: http.client.HTTPResponse object at ......)
它包含了請(qǐng)求回來(lái)的數(shù)據(jù)結(jié)果喊积。它包含一些屬性和方法,供我們處理返回的結(jié)果玄妈。

(1)乾吻、read():獲取響應(yīng)返回的數(shù)據(jù),只能用一次措近。和文件句柄一樣溶弟,只能運(yùn)行一次。#返回的是字節(jié)碼,decode() 解碼成字符串瞭郑。
(2)辜御、readline():讀取一行。沒(méi)必要屈张。
while True:
data = response.readline()
if data:
print(data)
(3)擒权、info():獲取響應(yīng)頭信息袱巨。 print(response.info())
(4)、geturl():獲取訪問(wèn)的url碳抄。 print(response.geturl())
(5)愉老、getcode() :返回狀態(tài)碼。 print(response.getcode())</pre>

二剖效、parse模塊

parse模塊是一個(gè)工具模塊嫉入,提供了需要對(duì)url處理的方法,用于解析url璧尸。
注意: url中只能包含ascii字符咒林,在實(shí)際操作過(guò)程中,get請(qǐng)求通過(guò)url傳遞的參數(shù)中會(huì)有大量特殊字符 (非ascii字符)爷光,例如漢字垫竞,那么就需要進(jìn)行url編碼。(一個(gè)中文用UTF-8有3個(gè)字節(jié)蛀序。)
導(dǎo)包:from urllib import parse(import urllib不行問(wèn)題同上)

方法:
1欢瞪、parse.quote():編碼
例: url = 'http://httpbin.org/get?username={}'
result = url.format(parse.quote('思齊')) #format方法別忘了
print(result)

結(jié)果為: http://httpbin.org/get?username=%E6%80%9D%E9%BD%8A

2、parse.unquote():反編碼徐裸,看看具體參數(shù)是什么遣鼓。
例1:
print(parse.unquote(result))

結(jié)果為: http://httpbin.org/get?username=思齊

3、parse.urlencode():在發(fā)送請(qǐng)求時(shí)倦逐,往往會(huì)需要傳遞很多的參數(shù)譬正,如果用字符串拼接會(huì)很麻 煩,該方法就是用來(lái)拼接url參數(shù)的宫补。
例1: args = {'username':'思齊','password':'小淘'}
res = parse.urlencode(args) #注意字典形式
print(res)

結(jié)果為: username=%E6%80%9D%E9%BD%8A&pd=123

例2:
args = {'username':'思齊','pd':'123'}
result = 'http://httpbin.org/get?{}'.format(parse.urlencode(args))
print(res)

結(jié)果為: http://httpbin.org/get?username=%E6%80%9D%E9%BD%8A&pd=123

注:url中規(guī)定多個(gè)參數(shù) & 連接檬姥。

4、parse.parse_qs(): 和parse.urlencode()是相反的粉怕,將它轉(zhuǎn)會(huì)字典健民。
例:print(parse.parse_qs(res))

結(jié)果為:{'username': ['思齊'], 'pd': ['123']}

{'http://httpbin.org/get?username': ['思齊'], 'pd': ['123']}

錯(cuò)誤信息:
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) #當(dāng)出現(xiàn)這種錯(cuò)誤時(shí)就是參數(shù)用的不是ascii碼。</pre>

三贫贝、error模塊

error模塊主要負(fù)責(zé)異常處理秉犹,如果請(qǐng)求出現(xiàn)錯(cuò)誤,我們可以用error模塊進(jìn)行處理稚晚,該模塊主要包含
URLError和HTTPError
?
導(dǎo)包:from urllib import error
1.URLError:是error模塊的基類,由request模塊產(chǎn)生的的異常都可以用這個(gè)類來(lái)處理崇堵。
?
2.HTTPError:是的子類,主要包含三個(gè)屬性:code:請(qǐng)求的狀態(tài)碼客燕、reason:錯(cuò)誤的原因鸳劳、headers: 響應(yīng)的報(bào)頭。
例:
try:
request.urlopen('http://www.reibang.com')#不是合法的用戶會(huì)被 ban也搓。
except error.HTTPError as e:
print(e.code)
print(e.reason)
print(e.headers)</pre>

四赏廓、robotparse模塊

robotparse模塊主要負(fù)責(zé)處理爬蟲協(xié)議文件涵紊,robots.txt的文件。
導(dǎo)包:from urllib import robotparse
https://www.amazon.cn/robots.txt #亞馬遜中國(guó)的爬蟲協(xié)議幔摸,如圖1</pre>

urllib3的使用

介紹:是一個(gè)基于python3的功能強(qiáng)大摸柄,友好的http客戶端。
保證線程安全(不需考慮鎖的問(wèn)題)既忆,連接池保持(而不向之前的一樣連一下關(guān)一下)驱负,支持重復(fù)請(qǐng)求、重定位患雇,保證代碼百分百被使用电媳。
?
導(dǎo)包:import urllib3
?
(1)構(gòu)造請(qǐng)求(request):
1.實(shí)例化一個(gè)PoolManager對(duì)象構(gòu)造請(qǐng)求,這個(gè)實(shí)例對(duì)象處理了連接池和線程安全的所有細(xì)節(jié),所以我們不用自行處 理。
例: http = urllib3.PoolManager()
在這里我出現(xiàn)了一個(gè)錯(cuò)誤庆亡,如下:
AttributeError: module 'urllib3的使用' has no attribute 'PoolManager'匾乓,我出現(xiàn) 這個(gè)原因是py文件所在的文件夾命名為urllib3。

2.用request()方法發(fā)送請(qǐng)求,可以用request()方法發(fā)送任意請(qǐng)求又谋,GET POST....
第一個(gè)參數(shù)是何種類型的請(qǐng)求;第二個(gè)參數(shù)是請(qǐng)求的網(wǎng)站拼缝。

例1:發(fā)送get請(qǐng)求
response = http.request('GET','http://httpbin.org/get ',b'User- Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64rv:73.0) Gecko/20100101 Firefox/73.0')
此處傳的二進(jìn)制數(shù)據(jù)報(bào)錯(cuò)

例2:發(fā)送POST請(qǐng)求
response = http.request('POST','http://httpbin.org/post',
fields={'hello':'world'})

3.請(qǐng)求傳入數(shù)據(jù)(data):

  • Headers:加入請(qǐng)求頭
    在request方法中添加字典格式的headers參數(shù)來(lái)指定請(qǐng)求頭。
    例:http = urllib3.PoolManager()
    response = http.request('POST','http://httpbin.org/get ',
    headers={'key':'value'})

  • Query parameters(字符串參數(shù)):
    *get,head,delete請(qǐng)求彰亥,可通過(guò)提供字典類型的參數(shù)fields來(lái)添加查詢參數(shù)咧七。(復(fù)習(xí)一 下:在urllib中我們通過(guò)parse.quote()編碼這里只需提供fields參數(shù)即可)
    例:http = urllib3.PoolManager()
    response = http.request('get','http://httpbin.org/get ',
    fields={'key':'value'})

*對(duì)于post,put請(qǐng)求,如果需要查詢參數(shù)任斋,需要通過(guò)url編碼將參數(shù)編碼正確格式再拼接到url中继阻。
例: 如圖1、2废酷、3
import urllib3
import urllib.parse import urlencode
import json
http = urllib3.PoolManager()
args = {'username':'思齊','password':'小淘'}

方法一:

result = urlencode(args)
url = 'http://httpbin.org/post?' + result #字符串拼接

方法二:

url1 = 'http://httpbin.org/post?{}'
url1 = url.format(parse.urlencode(args))


response = http.request('POST',url)
print(json.loads(response.data.decode('utf-8')))

*form data(表單數(shù)據(jù)):
對(duì)于post,put瘟檩,需要提供字典類型的參數(shù)fields來(lái)傳遞form表單數(shù)據(jù)。
response = http.request('post','http://httpbin.org/get ',
fields={'key':'value'})

*json數(shù)據(jù)
當(dāng)我們需要發(fā)送json數(shù)據(jù)時(shí)澈蟆,我們需要在request方法中傳入編碼后的二進(jìn)制數(shù)據(jù)類型的body參數(shù)墨辛,并 指定Content-Type的請(qǐng)求頭。

*文件上傳(通常不用這個(gè)上傳)
對(duì)于文件上傳,我們可以模仿瀏覽器表單的方式

對(duì)于二進(jìn)制數(shù)據(jù)上傳趴俘,我們用指定body的方式睹簇,并設(shè)置Content-Type的請(qǐng)求頭。

*注意:get,head,delete請(qǐng)求中提供fields參數(shù)會(huì)自動(dòng)拼接到url中寥闪,而對(duì)post,put請(qǐng)求中你提供的 fields參數(shù)會(huì)填寫到form表單中太惠,若你想拼接到url中只能主動(dòng)的使用字符串拼接的方法。
(2)http響應(yīng)對(duì)象提供 status疲憋、data凿渊、headers等屬性
例1:
import urllib3
http = urllib3.PoolManager()
response = http.request('get','http://httpbin.org/get')
print(type(response))#返回的是<class 'urllib3.response.HTTPResponse'>

也就是http響應(yīng)對(duì)象

print(response.data) #返回的是二進(jìn)制數(shù)據(jù)
print(response.headers)#返回的是<class 'urllib3._collections.HTTPHeaderDict'>

字典形式,因此可以通過(guò)鍵名看鍵值

print(response.status)

(3)返回的是 json格式數(shù)據(jù) 可以通過(guò)json模塊,loads為字典數(shù)據(jù)類型。
例:
import urllib3
import json
http = urllib3.PoolManager()
response = http.request('get','http://httpbin.org/ip')
print(json.load(response.data.decode('utf-8')))

// response.data.decode('utf-8') 解碼成字符串嗽元。

(4)返回的數(shù)據(jù)都是字節(jié)類型敛纲,對(duì)于大量的數(shù)據(jù)我們通過(guò)stream(流)來(lái)處理更好,也可以當(dāng)作一個(gè)文件對(duì)象來(lái)處理剂癌。
例1:流
import urllib3
http = urllib3.PoolManager()
response = http.request('get','http://httpbin.org/bytes/1024',
preload_content = False)
for i in response.stream(32): #一點(diǎn)點(diǎn)讀對(duì)內(nèi)存好淤翔,下圖片就可以用這種方法
print(i)

例2:文件對(duì)象
import urllib3
http = urllib3.PoolManager()
response = http.request('get','http://httpbin.org/bytes/1024', preload_content = False)
for line in response: #比如說(shuō)大文件可能5G大小,不能一次性回來(lái)佩谷,一批一批的回來(lái)
print(line)

(5)代理
例1:import urllib3
proxy = urllib3.ProxyManager('http://ip:端口號(hào)')
//用這個(gè)ip來(lái)幫助你來(lái)向某網(wǎng)站發(fā)送請(qǐng)求旁壮,保護(hù)了你自己的ip地址不被暴露。

response = proxy.request('get','http://httpbin.org/ip')
//http://httpbin.org/ip 查看請(qǐng)求的ip地址

print(response.data)

//遇到如下錯(cuò)誤urllib3.exceptions.MaxRetryError: HTTPConnectionPool(host='115.210.79.22', port=8118): Max retries exceeded with url: http://httpbin.org/ip (Caused by ProxyError('Cannot connect to proxy.', NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7f7ed4c1aef0>: Failed to establish a new connection: [Errno 111] Connection refused',))) 如果是初次使用代理谐檀,以上三 種錯(cuò)誤出現(xiàn)的原因基本是1.端口錯(cuò)誤2.代理類型不正確抡谐。 明確的一點(diǎn)是訪問(wèn)https站點(diǎn),要用https類型的代理。http同理桐猬。(當(dāng)然我找的是免費(fèi)代理麦撵,可能不好用。)
?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載溃肪,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者免胃。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市惫撰,隨后出現(xiàn)的幾起案子羔沙,更是在濱河造成了極大的恐慌,老刑警劉巖厨钻,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扼雏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡夯膀,警方通過(guò)查閱死者的電腦和手機(jī)诗充,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)棍郎,“玉大人其障,你說(shuō)我怎么就攤上這事⊥康瑁” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵蜈敢,是天一觀的道長(zhǎng)辜荠。 經(jīng)常有香客問(wèn)我,道長(zhǎng)抓狭,這世上最難降的妖魔是什么伯病? 我笑而不...
    開(kāi)封第一講書人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上午笛,老公的妹妹穿的比我還像新娘惭蟋。我一直安慰自己,他們只是感情好药磺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布告组。 她就那樣靜靜地躺著,像睡著了一般癌佩。 火紅的嫁衣襯著肌膚如雪木缝。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,541評(píng)論 1 305
  • 那天围辙,我揣著相機(jī)與錄音我碟,去河邊找鬼。 笑死姚建,一個(gè)胖子當(dāng)著我的面吹牛矫俺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掸冤,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼恳守,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了贩虾?” 一聲冷哼從身側(cè)響起催烘,我...
    開(kāi)封第一講書人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缎罢,沒(méi)想到半個(gè)月后伊群,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡策精,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年舰始,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片咽袜。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丸卷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出询刹,到底是詐尸還是另有隱情谜嫉,我是刑警寧澤,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布凹联,位于F島的核電站沐兰,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏蔽挠。R本人自食惡果不足惜住闯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧比原,春花似錦插佛、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至绑改,卻和暖如春谢床,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背厘线。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工识腿, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人造壮。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓渡讼,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親耳璧。 傳聞我的和親對(duì)象是個(gè)殘疾皇子成箫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容