日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python requests session刷新_Python Requests Session set-cookie不生效的坑

發(fā)布時間:2024/7/23 python 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python requests session刷新_Python Requests Session set-cookie不生效的坑 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我們知道 Python Requests庫 中的 Session 模塊有連接池和會話管理的功能,比如請求一個登錄接口后,會自動處理 response 中的 set-cookie,下次再請求時會自動把 cookie 帶上。但最近出現(xiàn)了一個詭異的事情,cookie 沒有自動帶上,導(dǎo)致請求 403。

一開始懷疑是登錄接口錯誤了,沒有 set-cookie,但抓包發(fā)現(xiàn) response header 中有 set-cookie,打印請求的 response.cookies 也有需要的 cookie。又懷疑是 set-cookie 的格式不對或者其它問題,但用瀏覽器實際跑了下流程,發(fā)現(xiàn)系統(tǒng)一切正常,那基本就是 requests 庫的問題了。

沒辦法,只能 debug 了,單步調(diào)試了幾輪,基本了解了 requests 的處理方式,首先把請求參數(shù)轉(zhuǎn)變?yōu)?Request 對象,然后對使用 prepare_request 對 Request 進行預(yù)處理,其中有一步 merge_cookies 的操作(還有各種其它處理),把傳入的 cookies 和 self.cookies merge 到 RequestsCookieJar 對象上去,這一步也沒啥問題,merged_cookies 變量也是對的。后續(xù)將預(yù)處理過的請求,通過內(nèi)置的 http adapter 發(fā)送出去。http adapter 底層是通過 urllib3.poolmanager 獲取到 urllib3.connectionpool 連接(這里是連接池的核心部分),再通過 conn.urlopen 實際發(fā)送請求。雖然跟蹤了解到了整個請求邏輯,但最終發(fā)出的請求還是沒有帶上需要的 cookie。

問題定位一度陷入僵局,只能再回顧上面的流程,cookie 肯定就是在 merged_cookies 和 conn.urlopen 之間沒的,再仔細(xì)觀察發(fā)現(xiàn),conn.urlopen 請求參數(shù)里面壓根沒有 cookie 字段。

1

2

3

4

5

6

7

8

9

10

11

12

13 # :param request: The :class:`PreparedRequest ` being sent.

resp=conn.urlopen(

method=request.method,

url=url,

body=request.body,

headers=request.headers,

redirect=False,

assert_same_host=False,

preload_content=False,

decode_content=False,

retries=self.max_retries,

timeout=timeout

)

查閱資料發(fā)現(xiàn),urllib3 的作者說,連接池只處理底層連接,cookie 跟蹤等事情應(yīng)該上層來做。大膽猜測,那 cookie 應(yīng)該是放在 header 里了,往前搗看看 request.headers 是怎么變動的(此時里面的 Cookie 字段確實不正確)。

再走查代碼發(fā)現(xiàn) prepare_request 里面是調(diào)用了 PreparedRequest.prepare,其中有一步 prepare_cookies,主要是調(diào)用了 cookielib.CookieJar.add_cookie_header 最終將 cookie 放到了 self.headers['Cookie']。但里面有個 request.has_header("Cookie") 的判斷,header 中沒有 Cookie 字段才會放,不知道為什么這么考慮(最新版 3.8 還是這樣),估計是 merge cookie 比較麻煩,但問題確實就出在這里,這次請求之前,Requests Session 已經(jīng)直接通過 headers['Cookie'] 設(shè)置了 cookie。復(fù)現(xiàn)代碼(修改自官方示例):

1

2

3

4

5

6

7

8

9

10 importrequests

s=requests.Session()

s.headers.update({

'Cookie':'k=v'

})

s.get('https://httpbin.org/cookies/set/sessioncookie/123456789')

r=s.get('https://httpbin.org/cookies')

print(r.text)

# {"cookies":{"k":"v"}}

雖然找到了問題的原因,但又不好解決,總不能不讓直接操作 headers['Cookie'] 吧,先不說無法限制使用者,而且之前的代碼已經(jīng)這樣做了,改動量非常之大。不過好在,現(xiàn)在自己用的框架是在 Requests Session 上封裝了一層,操作 header 都是調(diào)用的統(tǒng)一的 update_headers 方法:

1

2

3

4

5

6 defupdate_headers(self,headers):

"""

更新當(dāng)前會話的header

:param headers: header字典

"""

self.headers.update(headers)

對 headers['Cookie'] 的操作攔截一下,變成對 cookies 的操作:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15 defupdate_headers(self,headers):

"""

更新當(dāng)前會話的header

:param headers: header字典

"""

forheader_key,header_valueinheaders.items:

ifheader_key=='Cookie'orheader_key=='cookie':

c=Cookie.SimpleCookie()

c.load(header_value)

cookies={}

forkey,morselinc.items():

cookies[key]=morsel.value

requests.utils.add_dict_to_cookiejar(self.cookies,cookies)

delheaders[header_key]

self.headers.update(headers)

這樣即不用改之前的調(diào)用方代碼,也防止了后人掉坑。

參考資料

總結(jié)

以上是生活随笔為你收集整理的python requests session刷新_Python Requests Session set-cookie不生效的坑的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。