先扯扯淡
很久沒寫文章了,恐怕大部分人都忘了我了,沒辦法,人腦雖然有各種缺陷,但是垃圾回收機(jī)制卻是異常強(qiáng)大。
前段時(shí)間一直在忙swift文檔的翻譯,之后又是各種事,直接導(dǎo)致了公眾賬號(hào)死亡。不得不說,世界變化太快,本想著和我那一千個(gè)粉絲一起做安靜的美男子,但是天不遂人愿,各種事情接踵而至,最后不得不忍痛放棄了公眾號(hào)的更新。在此也對(duì)粉絲們說句后會(huì)無期,雖然你們可能看不到。
Python之父Guido為requests提出過一些有關(guān)發(fā)展路線的建議。
requests是一個(gè)Python的網(wǎng)絡(luò)請(qǐng)求庫,和urllib、httplib之流相比起來最大的優(yōu)點(diǎn)就是好用,requests官方標(biāo)榜的就是“我們的庫是給人用的哦”。此外,requests還支持https驗(yàn)證并且是線程安全的。
由于工作原因需要使用requests,確實(shí)好用,就順便把代碼研究了一番,記錄一些關(guān)鍵要點(diǎn),希望對(duì)諸位有所幫助。
一點(diǎn)提醒
本文只會(huì)講解requests的思路和結(jié)構(gòu),但是不會(huì)涉及到語法細(xì)節(jié),我認(rèn)為細(xì)節(jié)還是大家自己去研究最合適,我這人也懶,能少打幾個(gè)字就少打幾個(gè)字吧。
burst link??!
requests中有三巨頭(順便提個(gè)小問題,這里有人知道雷霆三巨頭嗎?沒錯(cuò)我說的是萎勃那三個(gè)):session,request和cookie。
先說最簡(jiǎn)單的cookie。
cookie嘛,就是把Python自帶的cookielib.CookieJar封裝了一下,讓它能適應(yīng)范圍更廣的輸入并且支持一些高端功能(比如檢測(cè)是否有相同cookie),如果大家想讀源碼的話,cookie是一個(gè)不錯(cuò)的切入點(diǎn)。
接著說session和request。
首先跟我讀一遍:session包含request。
session就是會(huì)話,一個(gè)session下可能有多個(gè)請(qǐng)求(因?yàn)榭赡苡衦edirect),提出session的目的是在多個(gè)請(qǐng)求之間保存相同的信息。舉個(gè)例子:如果沒有session,那你每次發(fā)請(qǐng)求都需要自己構(gòu)造cookie并傳入,但是有了session之后,只要第一次請(qǐng)求傳入cookie就可以,相同session中之后的請(qǐng)求都會(huì)自動(dòng)加上這些cookie。
需要注意,發(fā)送請(qǐng)求是在session中實(shí)現(xiàn)的,也就是說你要“讓session發(fā)送request”,request本身只是一個(gè)物體,它自己不會(huì)發(fā)送自己。
request有兩種形態(tài),第一形態(tài)是一個(gè)對(duì)象,就是我們?cè)诖a中常用的那種。但是這種形態(tài)是沒辦法直接發(fā)送的,大家都知道,網(wǎng)絡(luò)請(qǐng)求到最后其實(shí)都是一些字符串,所以如果要發(fā)送request的話必須啟用它的第二形態(tài),這時(shí)候它就叫做prepared request,也就是說“我準(zhǔn)備好了,我準(zhǔn)備好了,我準(zhǔn)備好了(海綿寶寶上線)”,此時(shí)request內(nèi)部的一些東西比如header、body就已經(jīng)轉(zhuǎn)換成字符串,可以發(fā)送了。
需要注意,只有第二形態(tài)的request可以發(fā)送。
下面看代碼。
resp = requests.get('http://www.baidu.com')
print resp.content
這是普通青年的用法,可以直觀地感受到requests到底多親切。
s = requests.Session()
s.headers.update({'laozizuidiao': 'laozizuidiao'})
s.get('http://www.gov.cn')
s.get('http://www.beijing.gov.cn')
這是作死青年的用法,前面我們說過,session會(huì)保存信息,所以現(xiàn)在我們每次發(fā)送請(qǐng)求的時(shí)候都會(huì)宣布我們是zuidiao的。
s = Session()
req = Request('GET', url,
data=data,
headers=header
)
prepped = req.prepare()
# 你這種情況……是要加錢的
resp = s.send(prepped,
stream=stream,
verify=verify,
proxies=proxies,
cert=cert,
timeout=timeout
)
print(resp.content)
最后是大家最期待的文藝青年的用法,我們先生成了session和request,然后讓request進(jìn)入第二形態(tài)(prepare),這時(shí)候萬事俱備只差send了,我們可以對(duì)request做任何愛做的事,然后最后爽完了send就行了。
我就不信你能看到這
還真看到這了?那我就說說看源碼的方法吧。
其實(shí)很簡(jiǎn)單,看源碼看的是思想。誰都會(huì)寫那些isinstanceof、if、init,關(guān)鍵要明白作者的設(shè)計(jì)思路到底是什么。
比如requests,看完了你應(yīng)當(dāng)問問自己,cookie為什么要封裝而不是直接用?request為什么要有兩個(gè)形態(tài)?設(shè)計(jì)session是為了解決什么問題?
只有理解了設(shè)計(jì)思路,再去看具體的細(xì)節(jié)實(shí)現(xiàn)才能有收獲,否則你看到的就是滿屏的raise、isinstanceof,這樣去看代碼恐怕是浪費(fèi)時(shí)間了。
最后祝你,身體健康,謝謝。