requests源碼淺析

先扯扯淡

很久沒寫文章了,恐怕大部分人都忘了我了,沒辦法,人腦雖然有各種缺陷,但是垃圾回收機(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í)間了。

最后祝你,身體健康,謝謝。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,755評(píng)論 11 349
  • 黎戈說:“為什么愛碎花的人,文字里都會(huì)有那樣的女性氣息。溫婉、戀物、窄窄的視野,呵手日常的體溫,關(guān)于電影...
    云云習(xí)習(xí)閱讀 233評(píng)論 1 0
  • 回家探望剛剛出院的父親?;蛟S是年齡大了,或許是身體底子太差,木后恢復(fù)不盡如人意。他還是覺得刀口很疼,翻身什么地很困...
    江漢漁歌閱讀 277評(píng)論 0 0
  • 以前的博客只能上傳圖片,不能上傳附件??梢园迅郊喝雸D片上傳。別人下載之后再解壓出附件 目標(biāo)文件1.txt壓縮到一...
    DragonersLi閱讀 1,255評(píng)論 0 0

友情鏈接更多精彩內(nèi)容