主頁 > 後端開發 > HTTP請求:requests的進階使用方法淺析

HTTP請求:requests的進階使用方法淺析

2023-06-17 07:24:40 後端開發

1 背景

上篇文章講解了requests模塊的基礎使用,其中有get、put、post等多種請求方式,使用data、json等格式做為請求引數,在請求體中添加請求頭部資訊的常見資訊,如:headers、cookies,以及對請求回應的處理方法,接下來講解一下requests的高級用法,

2 進階方法舉例

2.1 requests.request()

method:提交方式(get|post);

url:提交地址;

kwargs:14個控制訪問的引數;

常用的引數有:params、data、json、headers、cookies,已在上篇文章中介紹過了,感興趣的朋友,可以到上篇文章再回顧一下,以下將講解與示例其他引數的使用,

示例:

2.1.1 files

請求攜帶檔案,如果有的請求需要上傳檔案,可以用它來實作,

import requests

# 上傳檔案
f= {"files": open("favicon.ico", "rb") }
data = https://www.cnblogs.com/Jcloud/p/{"name": "上傳檔案"}

requests.request(
    method = 'POST', 
    url = 'http://127.0.0.1:8080/example/request',  
    data = https://www.cnblogs.com/Jcloud/p/data,
    files = f
)

需注意:favicon.ico檔案需和當前腳本在同一目錄下,如果不在,可以將檔案名稱修改為檔案路徑

import requests
from requests.auth import HTTPBasicAuth, HTTPDigestAuth

# 1、Basic Auth認證
res = requests.request(
    method = 'GET',
    url = 'http://127.0.0.1:8080/example/request',
    auth = HTTPBasicAuth("username", "password")
)
res.encoding = "gbk"

print(res.status)  # 200


# 2、DIGEST 認證
res = requests.request(
    method = 'GET',
    url = 'http://127.0.0.1:8080/example/request',
    auth = HTTPDigestAuth("username", "password")
)
res.encoding = "gbk"

print(res.status)  # 200

http auth認證的兩種方式,分別為Basic方式和Digest認證,其中:Basic Auth的優點是提供簡單的用戶驗證功能,其認證程序簡單明了,適合于對安全性要求不高的系統或設備中;同樣存在缺點:輸入的用戶名,密碼 base64編碼后會出現在Authorization里,很容易被決議出來,

那么Digest對比Basic認證有什么不同呢?

  • Digest思想,是使用一種亂數字串,雙方約定好對哪些資訊進行哈希運算,即可完成雙方身份的驗證,Digest模式避免了密碼在網路上明文傳輸,提高了安全性,但它依然存在缺點,例如認證報文被攻擊者攔截到攻擊者可以獲取到資源,
  • DIGEST 認證提供了高于 BASIC 認證的安全等級,但是和 HTTPS 的客戶端認證相比仍舊很弱,
  • DIGEST 認證提供防止密碼被竊聽的保護機制,但并不存在防止用戶偽裝的保護機制,
  • DIGEST 認證和 BASIC 認證一樣,使用上不那么便捷靈活,且仍達不到多數 Web 網站對高度安全等級的追求標準,因此它的適用范圍也有所受限,

2.1.2 timeout

請求和回應的超時時間,在網路回應延遲或者無回應時,可以通過設定超時時間,避免等待,

import requests

# 設定請求超時1秒,1秒后無回應,將拋出例外,1秒為connect和read時間總和
requests.request(
    method = 'POST',
    url = 'http://127.0.0.1:8080/example/request',
    json = {'k1' : 'v1', 'k2' : 'v2'},
    timeout = 1
)

# 分別設定connect和read的超時時間,傳入一個陣列
requests.request(
    method = 'POST',
    url = 'http://127.0.0.1:8080/example/request',
    json = {'k1' : 'v1', 'k2' : 'v2'},
    timeout = (5, 15)
)

# 永久等待
requests.request(
    method = 'POST',
    url = 'http://127.0.0.1:8080/example/request',
    json = {'k1' : 'v1', 'k2' : 'v2'},
    timeout = None
    # 或者洗掉timeout引數
)

# 捕捉超時例外
from requests.exceptions import ReadTimeout
try:
    res = requests.get('http://127.0.0.1:8080/example/request', timeout=0.1)
    print(res.status_code)
except ReadTimeout:
    print("捕捉到超時例外")

2.1.3 allow_redirects

設定重定向開關,

>>> import requests
>>> r = requests.get('http://github.com')
>>> r.url
'https://github.com/'

>>> r.status_code
200

>>> r.history
[<Response [301]>]

# 如果使用GET、OPTIONS、POST、PUT、PATCH或DELETE,則可以使用allow_redirects引數禁用重定向
>>> r = requests.get('http://github.com', allow_redirects=False)

>>> r.status_code
301

>>> r.history
[]

# 用HEAD啟動重定向
>>> r = requests.head('http://github.com', allow_redirects=True)

>>> r.url
'https://github.com/'

>>> r.history
[<Response [301]>]


import requests
import re

# 第一次請求
r1=requests.get('https://github.com/login')
r1_cookie=r1.cookies.get_dict() #拿到初始cookie(未被授權)
authenticity_token=re.findall(r'name="authenticity_token".*?value="https://www.cnblogs.com/Jcloud/p/(.*?)"',r1.text)[0] #從頁面中拿到CSRF TOKEN

# 第二次請求:帶著初始cookie和TOKEN發送POST請求給登錄頁面,帶上賬號密碼
data=https://www.cnblogs.com/Jcloud/p/{'commit':'Sign in',
    'utf8':'?',
    'authenticity_token':authenticity_token,
    'login':'[email protected]',
    'password':'password'
}


# 測驗一:沒有指定allow_redirects=False,則回應頭中出現Location就跳轉到新頁面,
# r2代表新頁面的response
r2=requests.post('https://github.com/session',
             data=https://www.cnblogs.com/Jcloud/p/data,
             cookies=r1_cookie
             )

print(r2.status_code) # 200
print(r2.url) # 看到的是跳轉后的頁面
print(r2.history) # 看到的是跳轉前的response
print(r2.history[0].text) # 看到的是跳轉前的response.text

# 測驗二:指定allow_redirects=False,則回應頭中即便出現Location也不會跳轉到新頁面,
# r2代表的仍然是老頁面的response
r2=requests.post('https://github.com/session',
             data=https://www.cnblogs.com/Jcloud/p/data,
             cookies=r1_cookie,
             allow_redirects=False
             )

print(r2.status_code) # 302
print(r2.url) # 看到的是跳轉前的頁面https://github.com/session
print(r2.history) # []

2.1.4 proxies

同添加headers方法一樣,代理引數是dict,

import requests
import re
def get_html(url):
    proxy = {
        'http': '120.25.253.234:812',
        'https' '163.125.222.244:8123'
    }
    heads = {}
    heads['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'
    req = requests.get(url, headers=heads,proxies=proxy)
    html = req.text
    return html
def get_ipport(html):
    regex = r'<td data-title="IP">(.+)</td>'
    iplist = re.findall(regex, html)
    regex2 = '<td data-title="PORT">(.+)</td>'
    portlist = re.findall(regex2, html)
    regex3 = r'<td data-title="型別">(.+)</td>'
    typelist = re.findall(regex3, html)
    sumray = []
    for i in iplist:
        for p in portlist:
            for t in typelist:
                pass
            pass
        a = t+','+i + ':' + p
        sumray.append(a)
    print('代理')
    print(sumray)
if __name__ == '__main__':
    url = 'http://www.baidu.com'
    get_ipport(get_html(url))

某些介面增加了防騷擾模式,對于大規模且頻繁的請求,可能會彈出驗證碼,或者跳轉到登錄驗證頁面,或者封禁IP地址,此時如果想要正常訪問,可以通過設定代理來解決這個問題,
除了基本的HTTP代理外,requests還支持SOCKS協議的代理,

# 安裝socks庫
pip3 install "requests[socks]"

# 進行代理
import requests

proxies = {
    'http': 'socks5://user:password@host:port',
    'https': 'socks5://user:password@host:port'
}
res = requests.get('http://www.baidu.com', proxies=proxies)
print(res.status)  # 200

2.1.5 hooks

即鉤子方法,requests庫只支持一個response的鉤子,即在回應回傳時,可以捎帶執行自定義方法,可以用于列印一些資訊、做一些回應檢查、或者向回應中添加額外的資訊,

import requests
url = 'http://www.baidu.com'

def verify_res(res, *args, **kwargs):
    print('url', res.url)
    res.status='PASS' if res.status_code == 200 else 'FAIL'

res = requests.get(url, hooks={'response': verify_res})
print(res.text) # <!DOCTYPE html><!--STATUS OK--><html> 
print(res.status) # PASS

2.1.6 stream

獲取內容立即下載開關,response會將報文一次性全部加載到記憶體中,如果報文過大,可以使用此引數,迭代下載,

import requests

url="http://www.baidu.com"

r = requests.get(url, stream=True)

# 決議response_body,以\n分割
for lines in r.iter_lines():
    print("lines:", lines)

# 決議response_body,以位元組分割
for chunk in r.iter_content(chunk_size=1024):
    print("chunk:", chunk)

2.1.7 verify

認證SSL證書開關,當發送HTTPS請求的時候,如果該網站的證書沒有被CA機構信任,程式將報錯,可以使用verify引數控制是否檢查SSL證書,

# 1、直接設定
import requests

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

# 2、請求時雖然設定了跳過檢查,但是程式運行時仍然會產生警告,警告中包含建議給我們的指定證書
# 可以通過設定,忽略屏蔽這個警告
from requests.packages import urllib3  # 如果報錯,則直接引入import urllib3

# 3、屏蔽警告
urllib3.disable_warnings()

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

# 4、通過cert直接宣告證書
# 本地需要有crt和key檔案(key必須是解密狀態,加密狀態的key是不支持的),并指定它們的路徑,
response = requests.get('https://www.12306.cn',cert('/path/server.crt','/path/key'))
print(response.status_code) # 200

2.2 requests庫的例外

如何判斷是否出現例外呢?

2.2.1 raise_for_status()

該方法在內部判斷res.status_code是否等于200,不是則產生例外HTTPError

示例:

# 1、HTTPError例外示例
import requests
from requests.exceptions import HTTPError

try:
    res = requests.post("http://127.0.0.1:8080/example/post")
    res.raise_for_status()
    # 等同于
    if res.status != 200:
        raise HTTPError

    return res

except HTTPError:
    return False

2.2.2 ReadTimeout

該例外型別,將會捕捉到因請求/回應超時的請求,

# Timeout超時例外
import requests
from requests.exceptions import ReadTimeout

try:
    res = requests.get('http://127.0.0.1:8080/example/post',timeout=0.5)
    print(res.status_code)
    return res

except ReadTimeout:
    print('timeout')

2.2.3 RequestException

該例外型別,將會捕捉到因無請求引起的例外請求,

# RquestError例外
import requests
from requests.exceptions import RequestException

try:
    res = requests.get('http://127.0.0.1:8080/example/post')
    print(res.status_code)
    return res

except RequestException:
    print('reqerror')

3 總結

看到這里,大家應該明白了,requests庫是一個比urilib2模塊更加簡潔的第三方庫,它具有如下的特點:

  • 支持HTTP連接保持和連接池
  • 支持使用cookie、session保持會話
  • 支持檔案上傳
  • 支持自動回應內容的編碼
  • 支持國際化的URL和Post資料自動編碼
  • 支持自動實作持久連接keep-alive

因此,requests這個高度封裝的模塊,可以使我們的HTTP請求,變得更加人性化,使用它將可以輕而易舉的完成瀏覽器請求的任何操作,充分詮釋了它的口號:“HTTP for Humans”,

作者:京東物流 駱銅磊

來源:京東云開發者社區

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/555330.html

標籤:Python

上一篇:Python 自動化測驗的配置層實作方式對標與落地

下一篇:返回列表

標籤雲
其他(161097) Python(38236) JavaScript(25498) Java(18244) C(15237) 區塊鏈(8271) C#(7972) AI(7469) 爪哇(7425) MySQL(7254) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5875) 数组(5741) R(5409) Linux(5347) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4599) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2436) ASP.NET(2404) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1984) 功能(1967) HtmlCss(1967) Web開發(1951) C++(1941) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1881) .NETCore(1863) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • HTTP請求:requests的進階使用方法淺析

    上篇文章講解了requests模塊的基礎使用,其中有get、put、post等多種請求方式,使用data、json等格式做為請求引數,在請求體中添加請求頭部資訊的常見資訊,如:headers、cookies,以及對請求回應的處理方法。接下來講解一下requests的高級用法。 ......

    uj5u.com 2023-06-17 07:24:40 more
  • Python 自動化測驗的配置層實作方式對標與落地

    Python中什么是組態檔,組態檔如何使用,有哪些支持的組態檔等內容,話不多說,讓我們一起看看吧~ ## 1 什么是組態檔? 組態檔是用于配置計算機程式的引數和初始化設定的檔案,如果沒有這些配置程式可能無法運行或是影響運行(運行速度、便捷性等),使用組態檔的好處在于,部分內容以及環境運行 ......

    uj5u.com 2023-06-17 07:24:35 more
  • 內網環境下批量安裝python庫

    最近組里安排了新內網,又要配環境。 眾所周知,內網安裝python庫需要先到www.pypi.org找到對應版本的包,然后再下載whl檔案,上傳到內網,再用`pip install "檔案地址"`去安裝。 這樣就會出現一個問題,鬼知道這個包需要的前置依賴是什么,pip會自動檢查前置依賴,然后自動從源 ......

    uj5u.com 2023-06-17 07:24:27 more
  • 如何有效管理爬蟲流量?

    本文分享自天翼云開發者社區《如何有效管理爬蟲流量?》,作者:劉****海 據國際知名金融廣告服務平臺提供商Dianomi的報告《2018 Robot traffic report》的資料,在互聯網上人類流量僅僅占了48.2%,也就是說,一個頁面的10000個點擊里面,大約5100個來自機器人。在航旅 ......

    uj5u.com 2023-06-17 07:24:15 more
  • Python初學者友好丨詳解引數傳遞型別

    摘要: 本文清晰地解釋了Python中的不同引數傳遞型別,并提供了示例代碼來說明每種型別的用法。對于初學者或不清楚Python傳參的讀者們來說是非常有益的,文中提供了足夠的資訊來理解和使用Python中的函式引數傳遞。 本文分享自華為云社區《提升Python函式呼叫靈活性:引數傳遞型別詳解》,作者: ......

    uj5u.com 2023-06-17 07:24:11 more
  • HTTP請求:requests模塊基礎使用必知必會

    http請求是常見的一種網頁協議,我們看到的各種網頁,其實都是發送了http請求得到了服務器的回應,從而將資料庫中復雜的資料以簡單、直觀的方式呈現出來,方便大眾閱讀、使用。而如何發送http請求呢?今天來探討一下使用requests模塊,達到高效、簡單的http請求操作。 ......

    uj5u.com 2023-06-17 07:24:07 more
  • 01. 組建知識星球服務體系

    ## 一、初衷: 因為想要進行各種技術點的訓練和學習,開發中需要使用各種各樣的開源技術框架,苦于沒有基礎服務支撐,所以想要建立一個專門的服務支撐系統,每年購買的云服務器配置底下,安裝一個Jenkins都跑不起來,所以自己購買了一個物理主機,記憶體加裝到`32G`,搭建自己的私人技術知識星球。 搭建一套 ......

    uj5u.com 2023-06-17 07:23:43 more
  • RabbitMQ快速使用代碼手冊

    本篇博客的內容為RabbitMQ在開發程序中的快速上手使用,側重于代碼部分,幾乎沒有相關概念的介紹,相關概念請參考以下csdn博客,兩篇都是我找的精華帖,供大家學習。本篇博客也持續更新~~~ ......

    uj5u.com 2023-06-17 07:23:38 more
  • Servlet重要類及其方法的應用

    # Servlet重要類及其方法的應用 ## Servlet重要類及其方法的應用 ### 1.1 HttpServlet的一些方法介紹 ```java // this.getInitParameter();得到初始化引數 // this.getServletConfig();得到servlet配置就 ......

    uj5u.com 2023-06-17 07:23:32 more
  • springBoot 自動裝配

    1.前言 自動裝配則是 SpringBoot 的核心,自動裝配是如何實作的呢?為什么我們只要引入一個 starter 組件依賴就能實作自動裝配呢,接下來就讓我們一起來探討下 SpringBoot 的自動裝配機制 2.自動裝配原理 提到自動裝配,那么你首先得知道spring的SPI(servicepr ......

    uj5u.com 2023-06-17 07:17:47 more