Python - requests


About

環境:win10 + Python3.6

requests庫是Python語言編寫,基於urllib,采用Apache2 Licensed開源協議的HTTP庫。

它相對於urllib更加方便,大大節約了代碼量,完全滿足了HTTP測試相關需求。

關於urllib:https://www.cnblogs.com/Neeo/articles/11520952.html

安裝

pip install requests
pip install -i https://pypi.doubanio.com/simple/ requests

使用之前需引入。

測試安裝是否成功

import requests   # 回車不報錯就算安裝成功
response = requests.get("https://www.baidu.com")
print(response.status_code)  # 200

有網的情況下,返回了200表示安裝成功。

requests庫的主要方法

方法 描述
requests.request() 構造一個請求,支持以下各種方法
requests.get() 獲取html的主要方法
requests.head() 獲取html頭部信息的主要方法
requests.post() 向html網頁提交post請求的方法
requests.put() 向html網頁提交put請求的方法
requests.patch() 向html提交局部修改的請求
requests.delete() 向html提交刪除請求
requests.Session() session相關

我們一起來看看都是怎么玩兒的。

requests.request()

這一節非常的重要!!!能用到的參數、基本都在這節展開。

請求接受的參數

requests.request(method, url, **kwargs)類能夠構造一個請求,支持不同的請求方式。

import requests

response = requests.request(method='get', url='https://www.baidu.com')
print(response.status_code)

request類中來看看幾個參數:

  • method:請求方式。
  • url:請求URL。
  • **kwargs:
    • params:字典或者字節序列,作為參數增加到url中,使用這個參數可以把一些鍵值對以k1=v1&k2=v2的模式增加到url中,get請求中用的較多。
    • data:字典、字節序列或者文件對象,重點作為向服務器提供或提交資源,作為請求的請求體,與params不同放在url上不同。它也可以接受一個字符串對象。
    • json:json格式的數據,可以向服務器提交json類型的數據。
    • headers:字典,定義請求的請求頭,比如可以headers字典定義user agent。
    • cookies:字典或者CookieJar。
    • auth:元組,用來支持HTTP認證功能。
    • files:字典,用來向服務器傳輸文件。
    • timeout:指定超時時間。
    • proxies:字典,設置代理服務器。
    • allow_redirects:開關,是否允許對URL進行重定向,默認為True。
    • stream:開關,是否對獲取內容進行立即下載,默認為False,也就是立即下載。這里需要說明的,stream一般應用於流式請求,比如說下載大文件,不可能一次請求就把整個文件都下載了,不現實,這種情況下,就要設置stream=True,requests無法將連接釋放回連接池,除非下載完了所有數據,或者調用了response.close。
    • verify:開關,用於SSL證書認證,默認為True。
    • cert:用於設置保存本地SSL證書路徑。

流式請求,指的不是請求是流,而是請求返回的數據流,返回一點取一點,而普通的請求是返回完畢你再取內容。

響應對象支持的屬性

import requests

response = requests.request(method='get', url='http://www.httpbin.org/get')

當一個請求被發送后,會有一個response響應。requests同樣為這個response賦予了相關方法:

  • response:響應對象。
  • response.status_code:請求返回狀態碼。
  • response.text:字符串形式的響應內容。
  • response.json():返回響應的是json類型的數據,如果響應的類型不是json,則拋出ValueError
  • response.content:二進制的響應內容。
  • response.iter_content(chunk_size):生成器,在stream=True的情況下,當遍歷生成器時,以塊的形式返回,也就是一塊一塊的遍歷要下載的內容。避免了遇到大文件一次性的將內容讀取到內存中的弊端,如果stream=False,全部數據作為一個塊返回。chunk_size參數指定塊大小。
  • response.iter_lines():生成器,當stream=True時,迭代響應數據,每次一行,也就是一行一行的遍歷要下載的內容。同樣避免了大文件一次性寫入到內存中的問題。當然,該方法不安全。至於為啥不安全,咱也不知道,咱也不敢問,主要是官網上沒說!經查,如果多次調用該方法,iter_lines不保證重新進入時的安全性,因此可能會導致部分收到的數據丟失。
  • response.cookies:響應中的cookie信息。
  • response.cookies.get_dict():以字典的形式返回cookies信息。
  • response.cookies.items():以列表的形式返回cookies信息。
  • response.headers:響應頭字典。取其中的指定key,response.headers.get('Content-Type', '哎呀,沒取到!')
  • response.reqeust:請求類型。
  • response.url:請求的URL。
  • response.reason:響應HTTP狀態的文本原因。
  • response.encoding:響應結果的編碼方式。
  • response.encoding = “gbk”:修該響應編碼方式,比如說響應結果的編碼是utf-8,通過這么response.encoding = “gbk”指定為gbk。
  • response.apparent_encoding:根據響應字節流中去chardet庫中匹配,返回編碼方式,並不保證100%准確。
  • response.history:以列表的形式返回請求記錄。列表內的請求以最老到最新排序。

see also:HTTP協議狀態碼 | chardet

requests.get()

requests.get(url, params=None, **kwargs)發送GET請求。相關參數:

  • url,請求的URL。
  • params參數: 可選url中的額外參數,字典或者字節流格式。
  • **kwargs:參見requests.request中的kwargs。

params參數

get請求難免會帶一些額外的參數K1=V1&K2=V2

我們可以手動的拼接:

import requests

response = requests.get(url='http://www.httpbin.org/get?k1=v1&k2=v2')
print(response.url)  # http://www.httpbin.org/get?k1=v1&k2=v2
print(response.json().get('args'))  # {'k1': 'v1', 'k2': 'v2'}

雖然沒問題,但是稍顯麻煩。

現在,我們可以使用params參數來解決這個問題。

import requests

params = {"user": "張開", "pwd": "666"}
response = requests.get(url='http://www.httpbin.org/get', params=params)
print(response.url)  # http://www.httpbin.org/get?user=%E5%BC%A0%E5%BC%80&pwd=666
print(response.json().get('args'))  # {'pwd': '666', 'user': '張開'}

headers

再來看,GET請求中如何攜帶headers。

import requests
headers = {"user-agent": UserAgent().random}
response = requests.get(url='http://www.httpbin.org/get', headers=headers)
print(response.json()['headers']['User-Agent'])  # Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-TW) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.2 Safari/533.18.5

關於 fake_useragent:https://www.cnblogs.com/Neeo/articles/11525001.html

cookies

來看,requests模塊如何攜帶cookis參數。

# 1. 登錄,獲取cookies值
data = {
    "userName": "=admin",
    "password": "1234"
}
response = requests.post(url="http://www.neeo.cc:6002/pinter/bank/api/login", data=data)
print(response.json())
print(response.cookies)
print(response.cookies.get_dict())


# 2. 在需要cookies驗證的時候,攜帶上剛才獲取到的cookies值
response = requests.get(url='http://www.neeo.cc:6002/pinter/bank/api/query?userName=admin', cookies=response.cookies.get_dict())
print(response.status_code)
print(response.json())

文件下載

如果你訪問的是一個小文件,或者圖片之類的,我們可以直接寫入到本地就完了,也就是不用管stream,讓它默認為False即可。

來個美女圖片提提神!

import requests
import webbrowser

url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1568638318957&di=1d7f37e7caece1c39af05b624f42f0a7&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201501%2F17%2F20150117224236_vYFmL.jpeg'

response = requests.get(url=url)
f = open('a.jpeg', 'wb')
f.write(response.content)
f.close()
webbrowser.open('a.jpeg')

過癮不?

那要是下載大文件,可就不能這么干了:

import requests
import webbrowser


url = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1568638318957&di=1d7f37e7caece1c39af05b624f42f0a7&imgtype=0&src=http%3A%2F%2Fimg3.duitang.com%2Fuploads%2Fitem%2F201501%2F17%2F20150117224236_vYFmL.jpeg'

response = requests.get(url=url, stream=True)
with open('a.jpeg', 'wb') as f:
    for chunk in response.iter_content(chunk_size=256):
        f.write(chunk)
webbrowser.open('a.jpeg')

使用response.iter_content(chunk_size=256)一塊一塊下載,並且可以指定chunk_size大小。

當然,也可以使用response.iter_lines一行一行遍歷下載,但是官網說不安全,所以,忘掉它吧。

requests.post()

requests.post(url, data=None, json=None, **kwargs)發送POST請求,相關參數:

  • url:請求的URL。
  • data:可選參數,請求中攜帶表單編碼的字典、bytes或者文件對象。
  • json:請求中攜帶json類型的數據。
  • **kwargs:參見requests.request中的kwargs。

在post請求中,data與json既可以是str類型,也可以是dict類型。

區別:

1、不管json是str還是dict,如果不指定headers中的content-type,默認為application/json

2、data為dict時,如果不指定content-type,默認為application/x-www-form-urlencoded,相當於普通form表單提交的形式

3、data為str時,如果不指定content-type,默認為application/json

4、用data參數提交數據時,request.body的內容則為a=1&b=2的這種形式,用json參數提交數據時,request.body的內容則為'{"a": 1, "b": 2}'的這種形式

實際應用時候,需要根據后端服務處理的方式來確定

data參數

import requests

url = 'http://www.httpbin.org/post'
# data為字典
data_dict = {"k1": "v1"}
response = requests.post(url=url, data=data_dict)
print(response.json())

# data為字符串
data_str = "abc"
response = requests.post(url=url, data=data_str)
print(response.json(), type(response.json()['data']))

# data為文件對象

file = open('a.jpg', 'rb')
response = requests.post(url=url, data=file)
print(response.json())

上述的基於data參數上傳文件,不如使用專門的files參數來的合適。

文件上傳

基於POST請求的文件上傳,使用files參數。

import requests
file = {"file": open('a.jpg', 'rb')}
response = requests.post('http://www.httpbin.org/post', files=file)
print(response.json())

json參數

import requests

url = 'http://www.httpbin.org/post'
response = requests.post(url=url, json={"user": "zhangkai"})
print(response.json())

requests.head()

requests.head(url, **kwargs)發送HEAD請求,相關參數:

  • url:請求URL。
  • **kwargs:參見requests.request中的kwargs。
import requests

url = 'http://httpbin.org/get'
response = requests.head(url=url)
print(response.headers)
'''
{
    'Access-Control-Allow-Credentials': 'true', 
    'Access-Control-Allow-Origin': '*', 
    'Content-Encoding': 'gzip', 
    'Content-Type': 'application/json', 
    'Date': 'Mon, 16 Sep 2019 10:58:07 GMT', 
    'Referrer-Policy': 'no-referrer-when-downgrade', 
    'Server': 'nginx', 
    'X-Content-Type-Options': 'nosniff', 
    'X-Frame-Options': 'DENY', 
    'X-XSS-Protection': '1; mode=block', 
    'Connection': 'keep-alive'
}
'''

使用requests.head(url, **kwargs)的優點就是以較少的流量獲得響應頭信息,也可以用在分頁中。

requests.put()

requests.put(url, data=None, **kwargs)發送PUT請求,相關參數:

  • url:請求URL。
  • data:可選參數,請求中攜帶表單編碼的字典、bytes或者文件對象。
  • **kwargs:參見requests.request中的kwargs。
import requests

url = 'http://www.httpbin.org/put'
data_dict = {"k1": "v1"}
response = requests.put(url=url, data=data_dict)
print(response.json())
'''
{
    'args': {}, 
    'data': '', 
    'files': {}, 
    'form': {'k1': 'v1'}, 
    'headers': {
        'Accept': '*/*', 
        'Accept-Encoding': 'gzip, deflate', 
        'Content-Length': '5', 
        'Content-Type': 'application/x-www-form-urlencoded', 
        'Host': 'www.httpbin.org', 
        'User-Agent': 'python-requests/2.19.1'
    }, 
    'json': None, 
    'origin': '1.202.184.14, 1.202.184.14', 
    'url': 'https://www.httpbin.org/put'
}
'''

requests.patch()

requests.patch(url, data=None, **kwargs)發送PATCH請求,相關參數:

  • url:請求URL。
  • data:可選參數,請求中攜帶表單編碼的字典、bytes或者文件對象。
  • **kwargs:參見requests.request中的kwargs。
import requests

url = 'http://www.httpbin.org/patch'
data_dict = {"k1": "v1"}
response = requests.patch(url=url, data=data_dict)
print(response.json())
'''
{   
    'args': {}, 
    'data': '', 
    'files': {}, 
    'form': {'k1': 'v1'}, 
    'headers': {
        'Accept': '*/*', 
        'Accept-Encoding': 'gzip, deflate', 
        'Content-Length': '5', 
        'Content-Type': 'application/x-www-form-urlencoded', 
        'Host': 'www.httpbin.org', 
        'User-Agent': 'python-requests/2.19.1'
    }, 
    'json': None, 
    'origin': '1.202.184.14, 1.202.184.14', 
    'url': 'https://www.httpbin.org/patch'
}
'''

在requests中,PATCH請求和PUT類似。而區別:

  • PATCH是對PUT方法的補充,用來對已知資源進行局部更新。
  • PATCH相比PUT更加節省帶寬。

requests.delete()

requests.head(url, **kwargs)發送DELETE請求,相關參數:

  • url:請求URL。
  • **kwargs:參見requests.request中的kwargs。
import requests

test_url = 'https://api.github.com'

def get_url(url):
    return '/'.join([test_url,url])

email = '24xxxxx48@qq.com'

def delete_email():
    r = requests.delete(get_url('user/emails'),json = email ,auth=('username','password'))
    print(r.status_code)
    print(r.text)
    print(r.request.headers)

delete_email()

將email,用戶名,密碼,換成自己的GitHub的。

requests.Session()

requests.Session()可以用來幫我們保持會話。

import requests
session = requests.Session()

session.get('http://www.httpbin.org/cookies/set/username/root')
response = session.get('http://www.httpbin.org/cookies')
print(response.json())  # {'cookies': {'username': 'root'}}

證書驗證

在之前,這個知識點還能拿12306網站舉例的時候.....

如果你請求的https協議的網址,那么人家網站首先會檢測你的證書是否是合法的,如果不合法,會拋出SSLError。怎么處理呢。

證書驗證這里,有兩種方式處理。第一種就是使用verify,是否進行證書校驗,默認是True。我們選擇不校驗。

import requests

response = requests.get(url='https://www.12306.cn', verify=False)
print(response.status_code)

但有的時候,會有一個Warnning警告,建議你加證書驗證。

我們可以選擇忽略這個警告:

import requests
from requests.packages import urllib3
urllib3.disable_warnings()
response = requests.get(url='https://www.12306.cn', verify=False)
print(response.status_code)

也可以選擇提供一個CA證書:

import requests

response = requests.get(url='https://www.12306.cn', cert=('/path/server.crt', 'path/key'))
print(response.status_code)

很明顯,我們沒有什么CA證書,這就看個熱鬧吧。

代理設置

代理:就是你訪問一個網站,其實並不是你直接訪問的,而是你發請求給A機器,A機器取請求B機器。B返回給A,A再返回給你。代理就是中間人的意思。為什么需要代理?因為:反爬蟲網站一般使用IP來識別一個機器。老是一個IP在不停訪問網站,該網站就會把這個IP拉入黑名單,不允許訪問。這時,就需要很多IP再擾亂反爬蟲工具的思維,避免封IP。

普通代理

import requests

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

response = requests.get(url='https://www.12306.cn', proxies=proxies)
print(response.status_code)

代理需要用戶名和密碼

import requests

proxies = {
    "http": "http://user:password@10.10.1.10:3128",
}
response = requests.get(url='https://www.12306.cn', proxies=proxies)
print(response.status_code)

支持sock代理

想要支持sock代理,那么首先要下載:

pip install requests[socks]

完事在用:

import requests
proxies = {
    'http': 'socks5://user:pass@host:port',
    'https': 'socks5://user:pass@host:port'
}
respone=requests.get('https://www.12306.cn',proxies=proxies)
print(respone.status_code)

超時

超時,在規定的時間無響應。

import requests
respone=requests.get('https://www.12306.cn', timeout=0.0001)

認證設置

有些網站,會彈出一個提示框,要求你輸入用戶名和密碼。

import requests
from requests.auth import HTTPBasicAuth

response = requests.get(url='https://www.12306.cn', auth=HTTPBasicAuth(username='user', password='123'))
print(response.status_code)

HTTPBasicAuth的簡寫形式:

import requests

response = requests.get(url='https://www.12306.cn', auth=('user', '123'))
print(response.status_code)

異常處理

異常處理相關異常類主要在requests.exceptions下,可以根據需求去翻看源碼。

import requests
from requests.exceptions import ReadTimeout, ConnectionError, RequestException

try:
    # RequestException
    # response = requests.get(url='https://www.12306.com')

    # ReadTimeout
    # response = requests.get(url='https://www.12306.cn', timeout=0.01)

    # ConnectionError ,斷網演示...
    response = requests.get(url='https://xueqiu.com/stock/f10/finmainindex.json')
    # print(response.status_code)
except ReadTimeout as e:
    print('ReadTimeout:', e)
except ConnectionError as e:
    print('ConnectionError:', e)
except RequestException as e:
    print('RequestException:', e)

歡迎斧正,that's all see also:[Requests: 讓 HTTP 服務人類](http://2.python-requests.org/zh_CN/latest/index.html#requests-http) | | | [urllib]( ) | [requests模塊 - egon](https://www.cnblogs.com/linhaifeng/articles/7785043.html) | [python3 requests詳解]( ) | [Python爬蟲系列(三):requests高級耍法]( ) | [requests庫入門08-delete請求](https://www.cnblogs.com/myal/p/9337384.html) | [請求接口時params和data的區別](https://blog.csdn.net/weixin_34130269/article/details/93193952) | [python request.post請求data參數與json參數的區別](https://blog.csdn.net/u011498011/article/details/96300354)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM