簡單描述執行流程 ??
Q:能簡單描述一下發送一個requests.get(url)
請求時,在requests庫內部的主要執行流程嗎?(從調用get
方法到收到響應)
- 入口委托:
get()
方法內部調用requests.request('GET', url)
。- Session 接管:
request()
方法會獲取或隱式創建一個Session
對象,并調用其request()
方法。Session
是核心,負責管理 Cookies、連接池復用和全局配置。- 請求準備:
Session
將傳入的參數(URL、headers、params 等)合并、編碼,構建成一個標準的PreparedRequest
對象。- 適配器與發送:
Session
根據 URL 協議 (http/https) 選擇對應的HTTPAdapter
。HTTPAdapter
利用底層的urllib3
連接池 獲取一個到目標服務器的連接(或新建),然后發送PreparedRequest
。- 處理響應:
- 處理重定向: 如果響應是重定向 (3xx) 且允許 (
allow_redirects=True
),會自動處理重定向鏈,直到獲得最終響應。- 構建響應: 將
urllib3
的原始響應封裝成requests.Response
對象,設置狀態碼、頭信息、Cookies (更新Session
)、歷史記錄等。- 返回結果: 最終
Response
對象返回給調用者。- 釋放資源: 通過
with requests.Session() as request:
顯式使用上下文管理器,確保在退出時自動調用request.close()
,釋放底層的urllib3
連接池資源,避免連接泄漏。
Session對象的作用
Q:Session 對象 (requests.Session
) 的主要作用是什么?它與直接調用 requests.get/post
在底層實現上有什么關鍵區別?
Session
是跨請求的持久化上下文管理器,核心解決 連接復用
、狀態保持
和 配置繼承
三大問題。
- 連接池復用:
- 底層通過
urllib3.PoolManager
復用 TCP 連接(尤其對同一主機發起多次請求時) - 避免重復 TCP 握手/TLS 協商,顯著提升性能
- 底層通過
- 狀態保持:
- 自動處理 Cookies:響應 Cookies 自動存儲,后續請求自動攜帶
- 持久化認證:auth 參數在會話內持續有效
- 配置繼承:
- 統一設置全局參數
- 支持全局
proxies
,hooks
,stream
等配置
注冊適配器邏輯
Q:Session
如何通過 mount()
方法注冊適配器?適配器與 URL 前綴的映射規則是什么?
- 創建 Session 對象時,自動注冊默認的
https
和http
適配器。
mount
根據適配器的前綴長度來按序存儲,前綴長的放前面,為了保證獲取適配器時能按最長前綴優先匹配。
- 由于按序存儲,獲取
adapter
時,前綴匹配成功就直接返回,能獲取到匹配的最長前綴適配器。