Python網絡請求之Requests庫

簡介

Requests是Python的一個第三方庫,它是基于urllib3來編寫的一個庫,采用Apache2 Licensed開源協議的HTTP庫。

它比Python原生的urllib使用起來更方便簡潔。

Requests庫的安裝

在終端命令行輸入以下命令來安裝Requests庫

pip install requests

Requests的使用

使用Requests發送網絡請求非常簡單。首先要做的是導入Requests模塊

import Requests

然后,嘗試獲取某個網頁

response = requests.get("http://www.baidu.com")

現在,我們有一個名為response的Response對象。我們可以從這個對象中獲取所有我們想要的的信息。

url是通過HTTP協議存取資源的Internet路徑,一個URL對應一個數據資源

HTTP協議對資源的操作

方法 說明
GET 請求獲取URL位置的資源
HEAD 請求獲取URL位置資源的響應消息報告,即獲得資源的頭部信息
POST 請求像URL位置的資源后附加新的消息
PUT 請求像URL位置存儲一個資源,覆蓋原URL位置的資源
PATCH 請求局部更新URL位置的資源,即改變該處資源的部分內容
DELETE 請求刪除URL位置存儲的資源

以上方法中,GET, HEAD是從服務器獲取信息到本地,PUT, POST, PATCH, DELETE是從本地像服務器提交信息。通過URL和命令管理資源,操作獨立無狀態,網絡通道及服務器成了黑盒子。

同樣的Requests庫也都支持這7種方法,我們就來看看都是怎么用的吧

import requests

response = requests.get("http://www.baidu.com")
response = requests.post('http://httpbin.org/post', data = {'key':'value'})
response = requests.put('http://httpbin.org/put', data = {'key':'value'})
response = requests.delete('http://httpbin.org/delete')
response = requests.head('http://httpbin.org/get')
response = requests.head('http://httpbin.org/get')
response = requests.options('http://httpbin.org/get')

都很不錯吧,但這也僅是Requests的冰山一角呢。

Requests.GET

使用Requests發送GET請求是非常方便的,也是用非常顯而易見的方式來發送請求的。

response = requests.get("http://www.baidu.com")

在我們平時請求網站的時候,經常是要為URL提供查詢字符串(Query string)傳遞一些數據的。如果你是手工構建URL,那么數據會key/value的形式置于URL中,跟在一個問號的后面。例如,http://httpbin.org/get?key=val。Requests允許你使用params關鍵字參數,以一個字符長字典來提供這些參數。舉例來說,如果你想傳遞ie=UTF-8wd=pythonhttps://www.baidu.com,那么可以這么做

param_dict = {
    'ie': 'UTF-8',
    'wd': 'python'
}
response = requests.get("https://www.baidu.com/s", params=param_dict)
print(response.url)

通過打印輸出URL,你能看到URL已經被正確編碼

https://www.baidu.com/s?ie=UTF-8&wd=python

注意字典里值為None的鍵都不會被添加到URL的查詢字符串里。

Requests.POST

在網絡請求中,除了GET方法從服務器指定位置獲取內容很常用外,還有一個POST方法,向服務器指定位置提交內容的方法也很常用。使用Requests庫對服務器發送POST請求也是非常簡顯的。

我們通常是要發送一些有HTML表單收集的信息,通過POST請求傳遞到服務器的指定位置的,要實現這個,只需要簡單地傳遞一個字典給data參數。你的數據字典在發出請求時會自動編碼為表單形式進行發送

data_dict={
    'key1': 'value1',
    'key2': 'value2'
}
response = requests.post("http://httpbin.org/post", data=data_dict)
print(response.text)

打印輸出結果:

...
"form": {
    "key2": "value2",
    "key1": "value1"
},
...

Requests除了可以為data參數傳遞一個dict,你還可以直接傳遞一個json參數

url = 'https://api.github.com/some/endpoint'
json_data = {'some': 'data'}
response = requests.post(url, json=json_data)

定制請求頭

我們在編寫爬蟲程序的時候,經常需要定制HTTP頭部,因為如果不定制請求頭的User-Agent,refer等信息,把程序偽裝成普通用戶的話,可能很容易就被目的網站程序識別出來是一個爬蟲程序給封殺了。Requests提供了我們一種定制HTTP請求頭的方式

url = "https://www.amzon.com"
headers = {
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0'
}
response = requests.get(url, headers=headers)

Cookie

如果某個響應中包含一些cookie,可以快速訪問它們:

url = "http://www.renren.com/PLogin.do"
data = {"email":"970138074@qq.com",'password':"pythonspider"}
resp = requests.get('http://www.baidu.com/')
print(resp.cookies)
print(resp.cookies.get_dict())

要想發送你的cookies到服務器,可以使用cookies參數

url = 'http://httpbin.org/cookies'
cookies = dict(cookies_are='working')
response = requests.get(url, cookies=cookies)
print(response.text)

打印結果:

'{"cookies": {"cookies_are": "working"}}'

使用代理

使用requests添加代理也非常簡單,只要在請求的方法中(比如get或者post)傳遞proxies參數就可以了。示例代碼如下

url = "http://httpbin.org/get"
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
}
proxy = {
    'http': '171.14.209.180:27829'
}
response = requests.get(url,headers=headers,proxies=proxy)

超時

可以告訴requests在經過以timeout參數設定的秒數時間之后停止等待響應,基本上所有生產代碼都應該使用這個參數。如果不使用,你的程序可能會永遠失去響應

response = requests.get('http://github.com', timeout=10)

Response對象

不管是給服務器指定位置發送GET請求,還是發送POST請求,都會等到一個服務器的響應,那就是Response對象。

response = requests.get("https://api.github.com/events")
print(response.text)

打印輸出

u'[{"repository":{"open_issues":0,"url":"https://github.com/...

Requests會自動解碼來自服務器的內容,大多數unicode字符集都能被無縫地解碼。

請求發出后,Requests會基于HTTP頭部對響應的編碼做出有根據的推測。當你訪問response.text的時候,Requests會使用推測的文本編碼,你可以找出Requests使用了什么編碼。并且能使用response.encoding屬性來改變它。

如果你改變了編碼,每當你訪問 r.text,Request都將會使用r.encoding 的新值。你可能希望在使用特殊邏輯計算出文本的編碼的情況下來修改編碼。比如 HTTP 和 XML 自身可以指定編碼。這樣的話,你應該使用 r.content 來找到編碼,然后設置 r.encoding 為相應的編碼。這樣就能使用正確的編碼解析 r.text 了。

在Requests中,也有一個內置的JSON解碼器,助你處理JSON數據

response = requests.get('https://api.github.com/events')
print(response.json())

打印輸出:

[{u'repository': {u'open_issues': 0, u'url': 'https://github.com/...

如果 JSON 解碼失敗, r.json() 就會拋出一個異常。例如,響應內容是 401 (Unauthorized),嘗試訪問 r.json() 將會拋出 ValueError: No JSON object could be decoded 異常。

需要注意的是,成功調用 r.json() 并不意味著響應的成功。有的服務器會在失敗的響應中包含一個 JSON 對象(比如 HTTP 500 的錯誤細節)。這種 JSON 會被解碼返回。要檢查請求是否成功,請使用 r.raise_for_status() 或者檢查 r.status_code 是否和你的期望相同。

Requests的Response對象還通過status_code屬性返回了響應狀態碼,為了方便檢查我們的請求是否獲得了正確的響應的我們可以通過這個屬性來做判斷。

response = requests.get("https://www.baidu.com")
if response.status_code == requests.codes.ok:
    print('響應成功,狀態%d' % response.status_code)
else:
    print('響應失敗')

Session會話對象

會話對象讓你能夠跨請求保持某些參數。它也會在同一個 Session 實例發出的所有請求之間保持 cookie, 期間使用 urllib3 的 connection pooling 功能。所以如果你向同一主機發送多個請求,底層的 TCP 連接將會被重用,從而帶來顯著的性能提升。

import requests

url = "http://www.renren.com/PLogin.do"
data = {"email":"970138074@qq.com",'password':"pythonspider"}
headers = {
    'User-Agent': "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"
}

# 登錄
session = requests.session()
session.post(url,data=data,headers=headers)

# 訪問大鵬個人中心
resp = session.get('http://www.renren.com/880151247/profile')

print(resp.text)

身份認證

許多Web服務都需要身份認證,并且有多種不同的認證類型。

許多要求身份認證的Web服務器接受HTTP Basic Auth。這是最簡單的一種身份認證,并且Requests對這種認證方式的支持是直接開箱即可用

from requests.auth import HTTPBasicAuth
response = requests.get('https://api.github.com/user', auth=HTTPBasicAuth('username', 'password'))
print(response.status_code)

打印輸出

<Response [200]>

HTTP Basic Auth是一種非常常見的身份驗證方式,Requests提供了一種簡寫方式

response = requests.get('https://api.github.com/user', auth=('username', 'password'))

看完了HTTP Basi Auth身份認證,再看一個常用的身份認證方式,HTTP Digest Auth

from requests.auth import HTTPDigestAuth
url = 'http://httpbin.org/digest-auth/auth/user/pass'
requests.get(url, auth=HTTPDigestAuth('user', 'pass'))
print(response.status_code)

打印輸出

<Response [200]>

最后再來看看OAuth1認證。Oauth 是一種常見的 Web API 認證方式。 requests-oauthlib 庫可以讓 Requests 用戶簡單地創建 OAuth 認證的請求。

import requests
from requests_oauthlib import OAuth1

url = 'https://api.twitter.com/1.1/account/verify_credentials.json'
auth = OAuth1('YOUR_APP_KEY', 'YOUR_APP_SECRET',
              'USER_OAUTH_TOKEN', 'USER_OAUTH_TOKEN_SECRET')
response = requests.get(url, auth=auth)
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容