Python 網絡請求利器:requests 包詳解與實戰

諸神緘默不語-個人技術博文與視頻目錄

文章目錄

  • 一、前言
  • 二、安裝方式
  • 三、基本使用
    • 1. 發起 GET 請求
    • 2. 發起 POST 請求
  • 四、requests請求調用常用參數
    • 1. URL
    • 2. 數據data
    • 3. 請求頭 headers
    • 4. 參數 params
    • 5. 超時時間 timeout
    • 6. 文件上傳 file:上傳純文本文件流
    • 7. json
  • 五. 響應的屬性和函數
    • 1. 屬性:headers、cookies、編碼格式
    • 2. 異常處理:raise_for_status()
  • 六、Session 會話對象(保持登錄態)
  • 七、進階用法
    • 1. 上傳壓縮文件
    • 2. 并發
  • 七、常見異常
    • 1. requests.exceptions.JSONDecodeError
    • 2. requests.exceptions.Timeout
    • 3. requests.exceptions.ProxyError: HTTPSConnectionPool
  • 八、實戰案例:爬取豆瓣電影 Top250(示例)
  • 本文撰寫過程中參考的其他網絡資料

一、前言

在進行網絡編程或爬蟲開發時,我們經常需要向網頁或服務器發送 HTTP 請求,獲取數據。這時,requests 包無疑是最受歡迎、最簡潔易用的 Python 庫之一。

相比原生的 urllib 模塊,requests 提供了更人性化的 API,更容易上手,幾乎成為了網絡請求的“標準庫”。

本文將介紹 requests 的基本用法、進階操作以及常見問題處理,配合實際代碼演示,帶你快速掌握這個神器!

https://httpbin.org/是一個簡單的用來模擬各種HTTP服務請求的網站,以下很多代碼示例都會用這個網站的鏈接來實現。
因為這個網站部署在海外,所以可能會出現網絡訪問的問題,可以通過部署到本地來解決。部署到本地可以參考官方教程,或者這篇博文:五、接口測試 — Httpbin介紹(請求調試工具) - 知乎

二、安裝方式

pip install requests

三、基本使用

關于get請求和post請求的區別請參考我撰寫的另一篇博文:Web應用中的GET與POST請求詳解

1. 發起 GET 請求

import requestsresponse = requests.get('https://httpbin.org/get')
print(response.status_code)      # 狀態碼
print(response.text)             # 響應內容(字符串)
print(response.json())           # 如果是 JSON,解析成字典

2. 發起 POST 請求

payload = {'username': 'test', 'password': '123456'}
response = requests.post('https://httpbin.org/post', data=payload)
print(response.json())

四、requests請求調用常用參數

1. URL

就是第一個參數,網站的鏈接地址

2. 數據data

請求攜帶的數據。
如果值是字符串或字節流,默認不設置Content-Type會設置。
如果值是字典、元組組成的列表或列表對象,會默認Content-Type會設置為application/x-www-form-urlencoded,也就是HTML表單形式的鍵值對數據。(對Content-Type的詳細介紹請見下一節headers參數)

import requests
import jsonpayload = {"key1": "value1", "key2": "value2"}# String payload in json format
r = requests.post("https://httpbin.org/post", data="a random sentence")
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))# String payload in json format
r = requests.post("https://httpbin.org/post", data=json.dumps(payload))
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))# String payload in json content type
r = requests.post("https://httpbin.org/post",data=json.dumps(payload),headers={"Content-Type": "application/json"},
)
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))# Dictionary payload
r = requests.post("https://httpbin.org/post", data=payload)
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))# List of tuples payload
payload_tuples = [("key1", "value1"), ("key2", "value2")]
r = requests.post("https://httpbin.org/post", data=payload_tuples)
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))# Bytes payload
payload_bytes = "key1=value1&key2=value2".encode("utf-8")
r = requests.post("https://httpbin.org/post", data=payload_bytes)
print(r.json())
print(r.json()["headers"].get("Content-Type","None"))

3. 請求頭 headers

一般會攜帶請求的Content-Type、系統信息(如使用的設備、編碼方式等)、認證信息、時間戳等

headers = {'User-Agent': 'MyUserAgent/1.0'}
response = requests.get('https://httpbin.org/headers', headers=headers)
print(response.json())

Content-Type的常見類型:
在這里插入圖片描述
(圖源1

4. 參數 params

這個在get請求中的效果就類似于直接在URL后面加?k=v

params = {'q': 'python'}
response = requests.get('https://httpbin.org/get', params=params)
print(response.url)  # 實際請求的完整 URL

輸出:https://httpbin.org/get?q=python

5. 超時時間 timeout

response = requests.get('https://httpbin.org/delay/3', timeout=2)

如果超過2秒沒響應,會拋出 requests.exceptions.Timeout 異常。

6. 文件上傳 file:上傳純文本文件流

files = {'file': open('test.txt', 'rb')}
response = requests.post('https://httpbin.org/post', files=files)
print(response.text)

↑ 需要注意的是雖然file參數確實可以直接這么傳文件流……但我沒咋見過真這么干的。
一般純文本不用file傳,一般都直接塞data里面帶過去。
非純文本文件流(二進制字節流),我一般看比較多的傳輸方式是把字節流轉換為base64編碼塞到data里帶。用base64編碼的代碼可參考我寫的另一篇博文:深入理解 Python 的 base64 模塊
(不過說實話直接用file參數傳文件流好像實際上背后也經過了base64編碼-解碼的過程,但是大家都這么干一定有大家的道理)

7. json

用json參數傳JSON對象(在Python 3中表現為字典對象)就相當于用data參數傳JSON對象、然后顯示設置Content-Type為application/json

payload = {'id': 1, 'name': 'chatgpt'}
response = requests.post('https://httpbin.org/post', json=payload)
print(response.json())

上面這個請求和下面這個請求是一樣的:

response = requests.post("https://httpbin.org/post",data=json.dumps(payload),headers={"Content-Type": "application/json"},
)
print(response.json())

作為對比可以看看另外兩種請求參數格式的效果(可以注意到第一種寫法返回的data和json值好歹還是一樣的,第二種寫法的話對象就放到form里了,因為是以表單對象形式來解析的):

response = requests.post("https://httpbin.org/post",data=json.dumps(payload)
)
print(response.json())response = requests.post("https://httpbin.org/post",data=payload
)
print(response.json())

五. 響應的屬性和函數

1. 屬性:headers、cookies、編碼格式

r = requests.get('https://httpbin.org/get')
print(r.headers)
print(r.cookies)
print(r.encoding)

2. 異常處理:raise_for_status()

如果status_code不是200就報錯

六、Session 會話對象(保持登錄態)

requests.Session() 可以模擬保持會話,適合需要登錄認證的網站。

s = requests.Session()
s.post('https://httpbin.org/cookies/set', data={'cookie': 'value'})
response = s.get('https://httpbin.org/cookies')
print(response.text)

七、進階用法

1. 上傳壓縮文件

  1. gzip實現
    import requests
    import gzip
    import jsondata = json.dumps({'key': 'value'}).encode('utf-8')
    compressed_data = gzip.compress(data)headers = {'Content-Encoding': 'gzip'}response = requests.post('https://httpbin.dev/api', data=compressed_data, headers=headers)
    response.raise_for_status()print("Gzip Compressed Request Status:", response.status_code)
    
  2. brotli實現
    import requests
    import brotlidata = json.dumps({'key': 'value'}).encode('utf-8')
    compressed_data = brotli.compress(data)headers = {'Content-Encoding': 'br'}response = requests.post('https://httpbin.dev/api', data=compressed_data, headers=headers)
    response.raise_for_status()print("Brotli Compressed Request Status:", response.status_code)
    

2. 并發

  1. httpx實現(來源于Concurrency vs Parallelism)
    import asyncio
    import httpx
    import time# Asynchronous function to fetch the content of a URL
    async def fetch(url):async with httpx.AsyncClient(timeout=10.0) as client:response = await client.get(url)return response.text# Concurrently fetch multiple URLs using asyncio.gather
    async def concurrent_fetch(urls):tasks = [fetch(url) for url in urls]return await asyncio.gather(*tasks)# Synchronous version to demonstrate performance difference
    def sync_fetch(urls):results = []for url in urls:response = httpx.get(url)results.append(response.text)return resultsdef run_concurrent():urls = ["http://httpbin.org/delay/2"] * 100  # Use the same delay for simplicitystart_time = time.time()# Running fetch requests concurrentlyasyncio.run(concurrent_fetch(urls))duration = time.time() - start_timeprint(f"Concurrent fetch completed in {duration:.2f} seconds")def run_sync():urls = ["http://httpbin.org/delay/2"] * 100  # Use the same delay for simplicitystart_time = time.time()# Running fetch requests synchronouslysync_fetch(urls)duration = time.time() - start_timeprint(f"Synchronous fetch completed in {duration:.2f} seconds")if __name__ == "__main__":print("Running concurrent version:")# Concurrent fetch completed in 2.05 secondsrun_concurrent()print("Running synchronous version:")# Synchronous fetch completed in 200.15 secondsrun_sync()
    
  2. threading實現
    import threading
    import requestsdef post_data(data):requests.post('https://httpbin.dev/api', json=data)# Sample data list
    data_list = [{'name': 'User1'}, {'name': 'User2'}]threads = []
    for data in data_list:thread = threading.Thread(target=post_data, args=(data,))threads.append(thread)thread.start()for thread in threads:thread.join()
    

關于并發的相關知識也可以參考我寫的另一篇博文:Python中的并發與并行

七、常見異常

1. requests.exceptions.JSONDecodeError

如果response帶的報文不是JSON,還調用response.json()函數,會報requests.exceptions.JSONDecodeError錯誤,完整的報錯信息類似這樣:

Traceback (most recent call last):File "myenv_path\Lib\site-packages\requests\models.py", line 974, in jsonreturn complexjson.loads(self.text, **kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\json\__init__.py", line 346, in 
loadsreturn _default_decoder.decode(s)^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\json\decoder.py", line 337, in decodeobj, end = self.raw_decode(s, idx=_w(s, 0).end())^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\json\decoder.py", line 355, in raw_decoderaise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)During handling of the above exception, another exception occurred:Traceback (most recent call last):File "tryrequests1.py", line 6, in <module>print(response.json())           # 如果是 JSON,解析成字典^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\requests\models.py", line 978, in jsonraise RequestsJSONDecodeError(e.msg, e.doc, e.pos)
requests.exceptions.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

2. requests.exceptions.Timeout

等待請求返回結果的時長超過了timeout參數設置的時長。

3. requests.exceptions.ProxyError: HTTPSConnectionPool

訪問URL失敗。
有時候網絡服務不穩定是臨時的,直接重試幾次就行。重試的策略可以參考我撰寫的另一篇博文:Python3:在訪問不可靠服務時的重試策略(持續更新ing…)

一個典型的由于臨時的網絡不穩定而產生的訪問失敗報錯輸出全文:

Traceback (most recent call last):File "myenv_path\Lib\site-packages\urllib3\connectionpool.py", line 789, in urlopenresponse = self._make_request(^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\urllib3\connectionpool.py", line 536, in _make_requestresponse = conn.getresponse()^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\urllib3\connection.py", line 507, in getresponsehttplib_response = super().getresponse()^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\http\client.py", line 1374, in getresponseresponse.begin()File "myenv_path\Lib\http\client.py", line 318, in beginversion, status, reason = self._read_status()^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\http\client.py", line 287, in _read_statusraise RemoteDisconnected("Remote end closed connection without"
http.client.RemoteDisconnected: Remote end closed connection without responseThe above exception was the direct cause of the following exception:urllib3.exceptions.ProxyError: ('Unable to connect to proxy', RemoteDisconnected('Remote end closed connection without response'))The above exception was the direct cause of the following exception:Traceback (most recent call last):File "myenv_path\Lib\site-packages\requests\adapters.py", line 667, in sendresp = conn.urlopen(^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\urllib3\connectionpool.py", line 843, in urlopenretries = retries.increment(^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\urllib3\util\retry.py", line 519, in incrementraise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='httpbin.org', port=443): Max retries exceeded with url: /cookies (Caused by ProxyError('Unable to connect to proxy', RemoteDisconnected('Remote end 
closed connection without response')))During handling of the above exception, another exception occurred:Traceback (most recent call last):File "tryrequests1.py", line 5, in <module>response = s.get('https://httpbin.org/cookies')^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\requests\sessions.py", line 602, in getreturn self.request("GET", url, **kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\requests\sessions.py", line 589, in requestresp = self.send(prep, **send_kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\requests\sessions.py", line 703, in sendr = adapter.send(request, **kwargs)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^File "myenv_path\Lib\site-packages\requests\adapters.py", line 694, in sendraise ProxyError(e, request=request)
requests.exceptions.ProxyError: HTTPSConnectionPool(host='httpbin.org', port=443): Max retries exceeded 
with url: /cookies (Caused by ProxyError('Unable to connect to proxy', RemoteDisconnected('Remote end closed connection without response')))

八、實戰案例:爬取豆瓣電影 Top250(示例)

import requests
from bs4 import BeautifulSoupheaders = {'User-Agent': 'Mozilla/5.0'}for start in range(0, 250, 25):url = f'https://movie.douban.com/top250?start={start}'r = requests.get(url, headers=headers)soup = BeautifulSoup(r.text, 'html.parser')titles = soup.find_all('span', class_='title')for title in titles:print(title.text)

本文撰寫過程中參考的其他網絡資料

  1. What is the difference between the ‘json’ and ‘data’ parameters in Requests? | WebScraping.AI
  2. python requests.post() 請求中 json 和 data 的區別 - 小嘉欣 - 博客園
  3. Python requests.post()方法中data和json參數的使用_requests.post中data和json是否可以同時設置-CSDN博客

在這里插入圖片描述


  1. Python requests POST ??

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/76221.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/76221.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/76221.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux入門四:Linux 編譯器

一、C 語言編譯器 GCC&#xff1a;開啟編程之旅 1.1 GCC 安裝&#xff1a;一站式工具鏈 GCC&#xff08;GNU Compiler Collection&#xff09;是 Linux 下最常用的 C/C 編譯器&#xff0c;支持多種編程語言。安裝命令&#xff08;適用于 Debian/Ubuntu 系統&#xff09;&…

建筑兔零基礎自學記錄69|爬蟲Requests-2

Requests庫初步嘗試 #導入requests庫 import requests #requests.get讀取百度網頁 rrequests.get(http://www.baidu.com) #輸出讀取網頁狀態 print(r.status_code) #輸出網頁源代碼 print(r.text) HTTP 狀態碼是三位數字&#xff0c;用于表示 HTTP 請求的結果。常見的狀態碼有…

Web測試流程及注意點

在Web工程過程中&#xff0c;基于Web系統的測試、確認和驗收是一項重要而富有挑戰性的工作。基于Web的系統測試與傳統的軟件測試不同&#xff0c;它不但需要檢查和驗證是否按照設計的要求運行&#xff0c;而且還要測試系統在不同用戶的瀏覽器端的顯示是否合適。 重要的是&…

基于MATLAB/simulink的信號調制仿真--AM調制

實驗內容&#xff1a; 假設y(t)(20.5*2cos&#xff08;2*pi*1000*t&#xff09;)*5cos&#xff08;2*pi*2*1e4*t&#xff09;調幅系統&#xff0c;請將一個頻率為1000HZ的余弦波信號&#xff0c;通過進行AM調制&#xff0c;載波信號頻率為20kHZ的余弦波&#xff0c;調制度ma0.…

通信協議詳解(十):PSI5 —— 汽車安全傳感器的“抗干擾狙擊手”

一、PSI5是什么&#xff1f; 一句話秒懂 PSI5就像傳感器界的“防彈信使”&#xff1a;在汽車安全系統&#xff08;如氣囊&#xff09;中&#xff0c;用兩根線同時完成供電數據傳輸&#xff0c;即便車禍時線路受損&#xff0c;仍能確保關鍵信號準確送達&#xff01; 基礎概念…

數據結構與算法-圖論-復習1(單源最短路,全源最短路,最小生成樹)

1. 單源最短路 單一邊權 BFS 原理&#xff1a;由于邊權為單一值&#xff0c;可使用廣度優先搜索&#xff08;BFS&#xff09;來求解最短路。BFS 會逐層擴展節點&#xff0c;由于邊權相同&#xff0c;第一次到達某個節點時的路徑長度就是最短路徑長度。 用法&#xff1a;適用…

【WRF理論第十七期】單向/雙向嵌套機制(含namelist.input詳細介紹)

WRF運行的單向/雙向嵌套機制 準備工作&#xff1a;WRF運行的基本流程namelist.input的詳細設置&time_control 設置&domain 嵌套結構&bdy_control 配置部分 namelist 其他注意事項Registry.EM 運行 ARW 嵌套雙向嵌套&#xff08;two-way nesting&#xff09;單向嵌套…

怎么查看蘋果手機和ipad的設備信息和ios udid

你知道嗎&#xff1f;我們每天使用的iPhone和iPad&#xff0c;其實隱藏著大量詳細的硬件與系統信息。除了常見的系統版本和序列號外&#xff0c;甚至連電池序列號、攝像頭序列號、銷售地區、芯片型號等信息&#xff0c;也都可以輕松查到&#xff01; 如果你是開發者、維修工程…

matlab內置的git軟件版本管理功能

1、matlab多人協作開發比普通的嵌入式軟件開發困難很多 用過matlab的人都知道&#xff0c;版本管理對于matlab來說真的很費勁&#xff0c;今天介紹的這個工具也不是說它就解決了這個痛點&#xff0c;只是讓它變得簡單一點。版本管理肯定是不可或缺的&#xff0c;干就完了 2、…

vscode集成deepseek實現輔助編程(銀河麒麟系統)【詳細自用版】

針對開發者用戶&#xff0c;可在Visual Studio Code中接入DeepSeek&#xff0c;實現輔助編程。 可參考我往期文章在銀河麒麟系統環境下部署DeepSeek&#xff1a;基于銀河麒麟桌面&&服務器操作系統的 DeepSeek本地化部署方法【詳細自用版】 一、前期準備 &#xff08…

Java 大廠面試題 -- JVM 深度剖析:解鎖大廠 Offe 的核心密鑰

最近佳作推薦&#xff1a; Java大廠面試高頻考點&#xff5c;分布式系統JVM優化實戰全解析&#xff08;附真題&#xff09;&#xff08;New&#xff09; Java大廠面試題 – JVM 優化進階之路&#xff1a;從原理到實戰的深度剖析&#xff08;2&#xff09;&#xff08;New&#…

數據庫實踐題目:在線書店管理系統

完整的數據庫實踐題目&#xff1a;在線書店管理系統 數據庫表結構及示例數據 書籍表(books) CREATE TABLE books ( book_id INT PRIMARY KEY, title VARCHAR(100) NOT NULL, author VARCHAR(50) NOT NULL, publisher VARCHAR(50), publish_year INT, category VARCHAR(30), …

Linux 入門指令(1)

&#xff08;1&#xff09;ls指令 ls -l可以縮寫成 ll 同時一個ls可以加多個后綴 比如 ll -at (2)pwd指令 &#xff08;3&#xff09;cd指令 cd .是當前目錄 &#xff08;4&#xff09;touch指令 &#xff08;5&#xff09;mkdir指令 &#xff08;6&#xff09;rmdir和rm…

圖靈逆向——題七-千山鳥飛絕

目錄列表 過程分析headers頭部M參數分析載荷x參數分析響應數據解密分析 代碼實現 一進來還是一個無限debugger&#xff0c;前面有講怎么過&#xff0c;這里直接過掉~ 老規矩&#xff0c;養成習慣&#xff0c;先看請求頭里有沒有加密參數發現好像是有個M&#xff0c;它是個32位…

上門預約洗鞋店小程序都具備哪些功能?

現在大家對洗鞋子的清洗條件越來越高&#xff0c;在家里不想去&#xff0c;那就要拿去洗鞋店去洗。如果有的客戶沒時間去洗鞋店&#xff0c;這個時候&#xff0c;有個洗鞋店小程序就可以進行上門取件&#xff0c;幫助沒時間的客戶去取需要清洗的鞋子&#xff0c;這樣豈不是既幫…

Node.js EventEmitter 深入解析

Node.js EventEmitter 深入解析 概述 Node.js 作為一種強大的 JavaScript 運行環境&#xff0c;以其異步、事件驅動特性在服務器端編程中占據了重要地位。EventEmitter 是 Node.js 中處理事件的一種機制&#xff0c;它允許對象&#xff08;稱為“發射器”&#xff09;發出事件…

C++11QT復習 (十九)

文章目錄 Day13 C 時間庫和線程庫學習筆記&#xff08;Chrono 與 Thread&#xff09;一、時間庫 <chrono>1.1 基本概念1.2 使用示例1.3 duration 字面量單位 二、線程庫 <thread>2.1 基本用法2.2 數據競爭&#xff08;Race Condition&#xff09;2.3 加鎖&#xff…

C++初階-C++的講解1

目錄 1.缺省(sheng)參數 2.函數重載 3.引用 3.1引用的概念和定義 3.2引用的特性 3.3引用的使用 3.4const引用 3.5.指針和引用的關系 4.nullptr 5.總結 1.缺省(sheng)參數 &#xff08;1&#xff09;缺省參數是聲明或定義是為函數的參數指定一個缺省值。在調用該函數是…

Redisson 實現分布式鎖

在平常的開發工作中&#xff0c;我們經常會用到鎖&#xff0c;那么鎖有什么用呢&#xff1f;鎖主要是控制對共享資源的訪問順序&#xff0c;防止多個線程并發操作導致數據不一致的問題。經常可能會聽到樂觀鎖、悲觀鎖、分布式鎖、行鎖、表鎖等等&#xff0c;那么我們今天總結下…

環境—Ubuntu24(py3.12)安裝streamlit(虛擬環境py3.9)

請盡可能不用Ubuntu24請直接跳7.查看解決方案 Action Log 在Ubuntu 24.04中更換為清華源的步驟【Bug】Python 3.12 on Ubuntu 24.04 is Externally Managed - PIP is broken 相關解決方案 從 Ubuntu 24.04 開始&#xff0c;有兩個選項&#xff1a; 1. install python pacakg…