爬蟲入門系列(二):優(yōu)雅的HTTP庫requests

爬蟲入門系列(一):快速理解HTTP協(xié)議中介紹了 HTTP 協(xié)議蔬墩,Python 提供了很多模塊來基于 HTTP 協(xié)議的網(wǎng)絡(luò)編程译打,urllib、urllib2拇颅、urllib3奏司、httplib、httplib2樟插,都是和 HTTP 相關(guān)的模塊韵洋,看名字覺得很反人類竿刁,更糟糕的是這些模塊在 Python2 與 Python3 中有很大的差異,如果業(yè)務(wù)代碼要同時(shí)兼容 2 和 3搪缨,寫起來會(huì)讓人崩潰食拜。

幸運(yùn)地是,繁榮的 Python 社區(qū)給開發(fā)者帶來了一個(gè)非常驚艷的 HTTP 庫 requests副编,一個(gè)真正給人用的HTTP庫负甸。它是 GitHUb 關(guān)注數(shù)最多的 Python 項(xiàng)目之一,requests 的作者是 Kenneth Reitz 大神痹届。

requests 實(shí)現(xiàn)了 HTTP 協(xié)議中絕大部分功能呻待,它提供的功能包括 Keep-Alive、連接池队腐、Cookie持久化蚕捉、內(nèi)容自動(dòng)解壓、HTTP代理柴淘、SSL認(rèn)證迫淹、連接超時(shí)、Session等很多特性为严,最重要的是它同時(shí)兼容 python2 和 python3敛熬。

快速入門

requests 的安裝可以直接使用 pip 方法:pip install requests

>>> import requests
# GET 請(qǐng)求
>>> response = requests.get("https://foofish.net")

返回的時(shí) Response 對(duì)象,Response 對(duì)象是 對(duì) HTTP 協(xié)議中服務(wù)端返回給瀏覽器的響應(yīng)數(shù)據(jù)的封裝梗脾,響應(yīng)的中的主要元素包括:狀態(tài)碼、原因短語盹靴、響應(yīng)首部炸茧、響應(yīng)體等等,這些屬性都封裝在Response 對(duì)象中稿静。

# 狀態(tài)碼
>>> response.status_code
200

# 原因短語
>>> response.reason
'OK'

# 響應(yīng)首部
>>> for name,value in response.headers.items():
...     print("%s:%s" % (name, value))
...
Content-Encoding:gzip
Server:nginx/1.10.2
Date:Thu, 06 Apr 2017 16:28:01 GMT

# 響應(yīng)內(nèi)容
>>> response.content

'<html><body>此處省略一萬字...</body></html>

requests 除了支持 GET 請(qǐng)求外梭冠,還支持 HTTP 規(guī)范中的其它所有方法,包括 POST改备、PUT控漠、DELTET、HEADT悬钳、OPTIONS方法盐捷。

>>> r = requests.post('http://httpbin.org/post', data = {'key':'value'})
>>> r = requests.put('http://httpbin.org/put', data = {'key':'value'})
>>> r = requests.delete('http://httpbin.org/delete')
>>> r = requests.head('http://httpbin.org/get')
>>> r = requests.options('http://httpbin.org/get')

構(gòu)建請(qǐng)求查詢參數(shù)

很多URL都帶有很長(zhǎng)一串參數(shù),我們稱這些參數(shù)為URL的查詢參數(shù)默勾,用"?"附加在URL鏈接后面碉渡,多個(gè)參數(shù)之間用"&"隔開,比如:http://fav.foofish.net/?p=4&s=20 母剥,現(xiàn)在你可以用字典來構(gòu)建查詢參數(shù):

>>> args = {"p": 4, "s": 20}
>>> response = requests.get("http://fav.foofish.net", params = args)
>>> response.url
'http://fav.foofish.net/?p=4&s=2'

構(gòu)建請(qǐng)求首部 Headers

requests 可以很簡(jiǎn)單地指定請(qǐng)求首部字段 Headers滞诺,比如有時(shí)要指定 User-Agent 偽裝成瀏覽器發(fā)送請(qǐng)求形导,以此來蒙騙服務(wù)器。直接傳遞一個(gè)字典對(duì)象給參數(shù) headers 即可习霹。

>>> r = requests.get(url, headers={'user-agent': 'Mozilla/5.0'})

構(gòu)建 POST 請(qǐng)求數(shù)據(jù)

requests 可以非常靈活地構(gòu)建 POST 請(qǐng)求需要的數(shù)據(jù)朵耕,如果服務(wù)器要求發(fā)送的數(shù)據(jù)是表單數(shù)據(jù),則可以指定關(guān)鍵字參數(shù) data淋叶,如果要求傳遞 json 格式字符串參數(shù)阎曹,則可以使用json關(guān)鍵字參數(shù),參數(shù)的值都可以字典的形式傳過去爸吮。

作為表單數(shù)據(jù)傳輸給服務(wù)器

>>> payload = {'key1': 'value1', 'key2': 'value2'}
>>> r = requests.post("http://httpbin.org/post", data=payload)

作為 json 格式的字符串格式傳輸給服務(wù)器

>>> import json
>>> url = 'http://httpbin.org/post'
>>> payload = {'some': 'data'}
>>> r = requests.post(url, json=payload)

Response中的響應(yīng)體

HTTP返回的響應(yīng)消息中很重要的一部分內(nèi)容是響應(yīng)體芬膝,響應(yīng)體在 requests 中處理非常靈活,與響應(yīng)體相關(guān)的屬性有:content形娇、text锰霜、json()。

content 是 byte 類型桐早,適合直接將內(nèi)容保存到文件系統(tǒng)或者傳輸?shù)骄W(wǎng)絡(luò)中

>>> r = requests.get("https://pic1.zhimg.com/v2-2e92ebadb4a967829dcd7d05908ccab0_b.jpg")
>>> type(r.content)
<class 'bytes'>
# 另存為 test.jpg
>>> with open("test.jpg", "wb") as f:
...     f.write(r.content)

text 是 str 類型癣缅,比如一個(gè)普通的 HTML 頁面,需要對(duì)文本進(jìn)一步分析時(shí)哄酝,使用 text友存。

>>> r = requests.get("https://foofish.net/understand-http.html")
>>> type(r.text)
<class 'str'>
>>> re.compile('xxx').findall(r.text)

如果使用第三方開放平臺(tái)或者API接口爬取數(shù)據(jù)時(shí),返回的內(nèi)容是json格式的數(shù)據(jù)時(shí)陶衅,那么可以直接使用json()方法返回一個(gè)經(jīng)過json.loads()處理后的對(duì)象屡立。

>>> r = requests.get('https://www.v2ex.com/api/topics/hot.json')
>>> r.json()
[{'id': 352833, 'title': '在長(zhǎng)沙,父母同住...

代理設(shè)置

當(dāng)爬蟲頻繁地對(duì)服務(wù)器進(jìn)行抓取內(nèi)容時(shí)搀军,很容易被服務(wù)器屏蔽掉膨俐,因此要想繼續(xù)順利的進(jìn)行爬取數(shù)據(jù),使用代理是明智的選擇罩句。如果你想爬取墻外的數(shù)據(jù)焚刺,同樣設(shè)置代理可以解決問題,requests 完美支持代理门烂。

import requests

proxies = {
  'http': 'http://10.10.1.10:3128',
  'https': 'http://10.10.1.10:1080',
}

requests.get('http://example.org', proxies=proxies)

超時(shí)設(shè)置

requests 發(fā)送請(qǐng)求時(shí)乳愉,默認(rèn)請(qǐng)求下線程一直阻塞,直到有響應(yīng)返回才處理后面的邏輯屯远。如果遇到服務(wù)器沒有響應(yīng)的情況時(shí)蔓姚,問題就變得很嚴(yán)重了,它將導(dǎo)致整個(gè)應(yīng)用程序一直處于阻塞狀態(tài)而沒法處理其他請(qǐng)求慨丐。

>>> import requests
>>> r = requests.get("http://www.google.coma")
...一直阻塞中

正確的方式的是給每個(gè)請(qǐng)求顯示地指定一個(gè)超時(shí)時(shí)間赂乐。

>>> r = requests.get("http://www.google.coma", timeout=5)
5秒后報(bào)錯(cuò)
Traceback (most recent call last):
socket.timeout: timed out

Session

爬蟲入門系列(一):快速理解HTTP協(xié)議中介紹過HTTP協(xié)議是一中無狀態(tài)的協(xié)議,為了維持客戶端與服務(wù)器之間的通信狀態(tài)咖气,使用 Cookie 技術(shù)使之保持雙方的通信狀態(tài)挨措。

有些網(wǎng)頁是需要登錄才能進(jìn)行爬蟲操作的挖滤,而登錄的原理就是瀏覽器首次通過用戶名密碼登錄之后,服務(wù)器給客戶端發(fā)送一個(gè)隨機(jī)的Cookie浅役,下次瀏覽器請(qǐng)求其它頁面時(shí)斩松,就把剛才的 cookie 隨著請(qǐng)求一起發(fā)送給服務(wù)器,這樣服務(wù)器就知道該用戶已經(jīng)是登錄用戶觉既。

import requests
# 構(gòu)建會(huì)話
session  = requests.Session()
# 登錄url
session.post(login_url, data={username, password})
# 登錄后才能訪問的url
r = session.get(home_url)
session.close()

構(gòu)建一個(gè)session會(huì)話之后惧盹,客戶端第一次發(fā)起請(qǐng)求登錄賬戶,服務(wù)器自動(dòng)把cookie信息保存在session對(duì)象中瞪讼,發(fā)起第二次請(qǐng)求時(shí)requests 自動(dòng)把session中的cookie信息發(fā)送給服務(wù)器钧椰,使之保持通信狀態(tài)。

項(xiàng)目實(shí)戰(zhàn)

最后是一個(gè)實(shí)戰(zhàn)項(xiàng)目符欠,如何用 requests 實(shí)現(xiàn)知乎自動(dòng)登錄并給用戶發(fā)私信嫡霞,我會(huì)在下一篇文章中進(jìn)行講解。

延伸閱讀:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末希柿,一起剝皮案震驚了整個(gè)濱河市诊沪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌曾撤,老刑警劉巖端姚,帶你破解...
    沈念sama閱讀 219,366評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異挤悉,居然都是意外死亡渐裸,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,521評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門装悲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昏鹃,“玉大人,你說我怎么就攤上這事衅斩∨韫耍” “怎么了怠褐?”我有些...
    開封第一講書人閱讀 165,689評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵畏梆,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我奈懒,道長(zhǎng)奠涌,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,925評(píng)論 1 295
  • 正文 為了忘掉前任磷杏,我火速辦了婚禮溜畅,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘极祸。我一直安慰自己慈格,他們只是感情好怠晴,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,942評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著浴捆,像睡著了一般蒜田。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上选泻,一...
    開封第一講書人閱讀 51,727評(píng)論 1 305
  • 那天冲粤,我揣著相機(jī)與錄音,去河邊找鬼页眯。 笑死梯捕,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的窝撵。 我是一名探鬼主播傀顾,決...
    沈念sama閱讀 40,447評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼忿族!你這毒婦竟也來了锣笨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,349評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤道批,失蹤者是張志新(化名)和其女友劉穎错英,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體隆豹,經(jīng)...
    沈念sama閱讀 45,820評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡椭岩,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,990評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了璃赡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片判哥。...
    茶點(diǎn)故事閱讀 40,127評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖碉考,靈堂內(nèi)的尸體忽然破棺而出塌计,到底是詐尸還是另有隱情,我是刑警寧澤侯谁,帶...
    沈念sama閱讀 35,812評(píng)論 5 346
  • 正文 年R本政府宣布锌仅,位于F島的核電站,受9級(jí)特大地震影響墙贱,放射性物質(zhì)發(fā)生泄漏热芹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,471評(píng)論 3 331
  • 文/蒙蒙 一惨撇、第九天 我趴在偏房一處隱蔽的房頂上張望伊脓。 院中可真熱鬧,春花似錦魁衙、人聲如沸报腔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,017評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纯蛾。三九已至邪狞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間茅撞,已是汗流浹背帆卓。 一陣腳步聲響...
    開封第一講書人閱讀 33,142評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留米丘,地道東北人剑令。 一個(gè)月前我還...
    沈念sama閱讀 48,388評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像拄查,于是被迫代替她去往敵國(guó)和親吁津。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,066評(píng)論 2 355

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

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理堕扶,服務(wù)發(fā)現(xiàn)碍脏,斷路器,智...
    卡卡羅2017閱讀 134,667評(píng)論 18 139
  • 基礎(chǔ)知識(shí) HTTP協(xié)議 我們?yōu)g覽網(wǎng)頁的瀏覽器和手機(jī)應(yīng)用客戶端與服務(wù)器通信幾乎都是基于HTTP協(xié)議稍算,而爬蟲可以看作是...
    腩啵兔子閱讀 1,488評(píng)論 0 17
  • http協(xié)議有http0.9典尾,http1.0,http1.1和http2三個(gè)版本糊探,但是現(xiàn)在瀏覽器使用的是htt...
    一現(xiàn)_閱讀 1,865評(píng)論 0 3
  • 1.發(fā)送請(qǐng)求: import requests # 獲取數(shù)據(jù) #r是一個(gè) response 對(duì)象钾埂。包含請(qǐng)求返回的內(nèi)...
    阿爾卑斯山上的小灰兔閱讀 1,399評(píng)論 0 3
  • 1. 網(wǎng)絡(luò)基礎(chǔ)TCP/IP HTTP基于TCP/IP協(xié)議族,HTTP屬于它內(nèi)部的一個(gè)子集科平。 把互聯(lián)網(wǎng)相關(guān)聯(lián)的協(xié)議集...
    yozosann閱讀 3,444評(píng)論 0 20