欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python爬蟲入門教程--優(yōu)雅的HTTP庫requests(二)

 更新時間:2017年05月25日 09:30:10   作者:FOOFISH  
requests 實現(xiàn)了 HTTP 協(xié)議中絕大部分功能,它提供的功能包括 Keep-Alive、連接池、Cookie持久化、內(nèi)容自動解壓、HTTP代理、SSL認(rèn)證等很多特性,下面這篇文章主要給大家介紹了python爬蟲入門中關(guān)于優(yōu)雅的HTTP庫requests的相關(guān)資料,需要的朋友可以參考下。

前言

urllib、urllib2、urllib3、httplib、httplib2 都是和 HTTP 相關(guān)的 Python 模塊,更糟糕的是這些模塊在 Python2 與 Python3 中有很大的差異,如果業(yè)務(wù)代碼要同時兼容 2 和 3,寫起來會讓人崩潰。

好在,還有一個非常驚艷的 HTTP 庫叫 requests,它是 GitHUb 關(guān)注數(shù)最多的 Python 項目之一,requests 的作者是 Kenneth Reitz 大神。

requests 實現(xiàn)了 HTTP 協(xié)議中絕大部分功能,它提供的功能包括 Keep-Alive、連接池、Cookie持久化、內(nèi)容自動解壓、HTTP代理、SSL認(rèn)證、連接超時、Session等很多特性,最重要的是它同時兼容 python2 和 python3。requests 的安裝可以直接使用 pip 方法:pip install requests

發(fā)送請求

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

響應(yīng)內(nèi)容

請求返回的值是一個Response 對象,Response 對象是對 HTTP 協(xié)議中服務(wù)端返回給瀏覽器的響應(yīng)數(shù)據(jù)的封裝,響應(yīng)的中的主要元素包括:狀態(tài)碼、原因短語、響應(yīng)首部、響應(yīng)體等等,這些屬性都封裝在Response 對象中。

# 狀態(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 請求外,還支持 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')

查詢參數(shù)

很多URL都帶有很長一串參數(shù),我們稱這些參數(shù)為URL的查詢參數(shù),用"?"附加在URL鏈接后面,多個參數(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'

請求首部

requests 可以很簡單地指定請求首部字段 Headers,比如有時要指定 User-Agent 偽裝成瀏覽器發(fā)送請求,以此來蒙騙服務(wù)器。直接傳遞一個字典對象給參數(shù) headers 即可。

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

請求體

requests 可以非常靈活地構(gòu)建 POST 請求需要的數(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)

響應(yīng)內(nèi)容

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 類型,比如一個普通的 HTML 頁面,需要對文本進(jìn)一步分析時,使用 text。

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

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

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

代理設(shè)置

當(dāng)爬蟲頻繁地對服務(wù)器進(jìn)行抓取內(nèi)容時,很容易被服務(wù)器屏蔽掉,因此要想繼續(xù)順利的進(jìn)行爬取數(shù)據(jù),使用代理是明智的選擇。如果你想爬取墻外的數(shù)據(jù),同樣設(shè)置代理可以解決問題,requests 完美支持代理。這里我用的是本地 ShadowSocks 的代理,(socks協(xié)議的代理要這樣安裝 pip install requests[socks]

import requests

proxies = {
 'http': 'socks5://127.0.0.1:1080',
 'https': 'socks5://127.0.0.1:1080',
}

requests.get('https://foofish.net', proxies=proxies, timeout=5)

超時設(shè)置

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

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

正確的方式的是給每個請求顯示地指定一個超時時間。

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

Session

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

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

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

構(gòu)建一個session會話之后,客戶端第一次發(fā)起請求登錄賬戶,服務(wù)器自動把cookie信息保存在session對象中,發(fā)起第二次請求時requests 自動把session中的cookie信息發(fā)送給服務(wù)器,使之保持通信狀態(tài)。

項目實戰(zhàn)

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

總結(jié)

好了,以上就是這篇文章的全部內(nèi)容,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。

相關(guān)文章

最新評論