完全对齐目标 ck
This commit is contained in:
+41
-8
@@ -56,6 +56,8 @@ class DouyuLogin:
|
||||
WEBLOGIN_API = "https://msg.douyu.com/webLogin"
|
||||
CSRF_API = "https://www.douyu.com/japi/carnival/nc/common/generateCsrf"
|
||||
CSRF_REFERER = "https://www.douyu.com/pages/live-peace-handbook/web/shop?ditchname=pass0&roomId=9263298"
|
||||
ACF_CCN_API = "https://www.douyu.com/curl/csrfNlApi/getCsrfCookie"
|
||||
ACF_CCN_REFERER = "https://www.douyu.com/pages/ord-task-center?clientType=web&panelSource=1&rid=0"
|
||||
LOGIN_REFERER = (
|
||||
"https://passport.douyu.com/index/login?"
|
||||
"passport_reg_callback=PASSPORT_REG_SUCCESS_CALLBACK&"
|
||||
@@ -734,8 +736,9 @@ class DouyuLogin:
|
||||
except Exception as e:
|
||||
logger.warning(f"WebLogin请求失败(不影响登录): {e}")
|
||||
|
||||
# 登录成功后访问斗鱼 Web CSRF 接口,补齐 cvl_csrf_token;响应里的 acf_ccn 也会进入 session cookie jar。
|
||||
# 登录成功后补齐 Web 侧 Cookie,再导出完整 CK。
|
||||
self._generate_csrf_cookie()
|
||||
self._generate_acf_ccn_cookie()
|
||||
|
||||
return self._format_cookie_string()
|
||||
|
||||
@@ -743,8 +746,7 @@ class DouyuLogin:
|
||||
"""
|
||||
访问斗鱼 generateCsrf 接口,从 Set-Cookie 中同步 cvl_csrf_token。
|
||||
|
||||
requests.Session 会自动接收响应中的 Set-Cookie,所以这里不只保存
|
||||
cvl_csrf_token;接口额外下发的 acf_ccn 等 Cookie 也会保留到最终 CK。
|
||||
requests.Session 会自动接收响应中的 Set-Cookie,最终导出时会保留到 CK。
|
||||
"""
|
||||
logger.info("补齐CSRF Cookie...")
|
||||
headers = {
|
||||
@@ -780,14 +782,45 @@ class DouyuLogin:
|
||||
if not csrf_token:
|
||||
raise ValueError("生成CSRF失败: 响应没有 cvl_csrf_token")
|
||||
|
||||
if cookies.get('acf_ccn'):
|
||||
logger.info("已同步 acf_ccn Cookie")
|
||||
else:
|
||||
logger.warning("generateCsrf 响应未同步 acf_ccn Cookie")
|
||||
|
||||
logger.info("CSRF Cookie已补齐")
|
||||
return csrf_token
|
||||
|
||||
def _generate_acf_ccn_cookie(self) -> str:
|
||||
"""访问 getCsrfCookie 接口,从 Set-Cookie 中同步 acf_ccn。"""
|
||||
logger.info("补齐 acf_ccn Cookie...")
|
||||
headers = {
|
||||
'Accept': 'application/json, text/plain, */*',
|
||||
'Accept-Language': 'zh-CN,zh;q=0.9',
|
||||
'Cache-Control': 'no-cache',
|
||||
'Pragma': 'no-cache',
|
||||
'Priority': 'u=1, i',
|
||||
'Referer': self.ACF_CCN_REFERER,
|
||||
'Sec-CH-UA': '"Google Chrome";v="149", "Chromium";v="149", "Not)A;Brand";v="24"',
|
||||
'Sec-CH-UA-Mobile': '?0',
|
||||
'Sec-CH-UA-Platform': '"macOS"',
|
||||
'Sec-Fetch-Dest': 'empty',
|
||||
'Sec-Fetch-Mode': 'cors',
|
||||
'Sec-Fetch-Site': 'same-origin',
|
||||
# 该接口抓包没有 Origin、表单 Content-Type 和 X-Requested-With。
|
||||
'Origin': None,
|
||||
'Content-Type': None,
|
||||
'X-Requested-With': None,
|
||||
}
|
||||
response = self._request('get', self.ACF_CCN_API, headers=headers)
|
||||
response.raise_for_status()
|
||||
|
||||
cookies = self.session.cookies.get_dict()
|
||||
acf_ccn = cookies.get('acf_ccn', '') or response.cookies.get('acf_ccn', '')
|
||||
if acf_ccn and not cookies.get('acf_ccn'):
|
||||
# 极少数情况下响应 Cookie 未合入 get_dict,手动补到斗鱼域名下。
|
||||
self.session.cookies.set('acf_ccn', acf_ccn, domain='.douyu.com', path='/')
|
||||
|
||||
if not acf_ccn:
|
||||
raise ValueError("补齐 acf_ccn 失败: 响应没有 acf_ccn")
|
||||
|
||||
logger.info("acf_ccn Cookie已补齐")
|
||||
return acf_ccn
|
||||
|
||||
def _format_cookie_string(self) -> str:
|
||||
"""把当前 session 中的 Cookie 格式化为可导出的 CK 字符串。"""
|
||||
cookies = self.session.cookies.get_dict()
|
||||
|
||||
@@ -8,99 +8,10 @@ cvl_csrf_token=62083f188904477e9bc1c5a70537145c; acf_ccn=8b025ffcbf403d5e0d880ad
|
||||
|
||||
======
|
||||
自己跑的
|
||||
dy_accounts_main=; dy_auth=0208CrOVxM5sDK9%2F5WrkVdZhuB4HSkgVod%2F7g6BhzIwaz0KjIUNW%2FkwQP2aNlqlgUCmz40FFwmZlH%2FV%2BKs%2FIfw9NgitHrJUx8w%2F8H1H2Dati3ezwI%2BOR6WYLeQ; wan_auth37wan=36a436a51f20daPv%2B2XfNSB6x4uSc4S%2Bu1ygA0cT%2FjaoFSAvJcFQtC6dlTLGIzT2xhSM8Al1gmJumyROhJOrnC5NFtcWbzxzPwbJEetjQKR58fRcTCcj; LTP0=eyJhbGciOiJtZDUiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOlsicGFzc3BvcnQiXSwiY3QiOjAsImN0aW1lIjoxNzgyMjMwOTMwLCJleHAiOjE3OTc5OTg5MzgsImtleSI6ImR5LWp3dC1tZDUiLCJsdGsiOiIzOWU4ZDZhYzBiZGYwNTEzIiwibHRraWQiOjcxODUwNjE0LCJzdWIiOiJsdCIsInVpZCI6MTAzMDAyMzc0MH0.MjQ3NGQzNWQ1MjkyOGQ1NzUxZjA1OTNiYzAxMmE5MWY; last_login_way=nickname; PHPSESSID=8a7ldg51tuapcngdkdice6pab0; acf_auth=dc71BJkxslSfnGLHIcCLvMmxXDfqt72pB0VW53Z30z7RZfS5NSZRGFvrNShEuX6k0YxPv%2B71Cnhl6O%2FTRQYciZ9l7RhRMqs0ykAhm%2Ftb1ulawonh0V2hoBmU0w; acf_jwt_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJtZDUifQ.eyJ1aWQiOjEwMzAwMjM3NDAsImN0IjowLCJzdWIiOiJzdCIsImF1ZCI6WyJkeSIsIm5vbmUiXSwiYml6IjoxLCJsdGtpZCI6NzE4NTA2MTQsInN0ayI6IjliNDEyMGE2MTFkMDA3NjAiLCJleHAiOjE3ODI4MzU3MzAsImlhdCI6MTc4MjIzMDkzMCwia2V5IjoiZHktand0LW1kNSJ9.ZmE0Y2IwMDIzMmZhZTQzZGIzMmMzNmY2ZWY1NGNjNjQ; acf_dmjwt_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJtZDUifQ.eyJ1aWQiOjEwMzAwMjM3NDAsImN0IjowLCJzdWIiOiJzdCIsImF1ZCI6WyJkbSIsIm5vbmUiXSwiYml6IjoxLCJsdGtpZCI6NzE4NTA2MTQsInN0ayI6IjliNDEyMGE2MTFkMDA3NjAiLCJleHAiOjE3ODI4MzU3MzAsImlhdCI6MTc4MjIzMDkzMCwia2V5IjoiZHktand0LW1kNSJ9.M2QyMWMxYjI2NjY5OTlkMGYyOGVlYTU3ZmRlZTg4YzE; acf_uid=1030023740; acf_username=1030023740; acf_nickname=%E7%94%A8%E6%88%B74965059115; acf_own_room=0; acf_groupid=1; acf_phonestatus=1; acf_avatar=https%3A%2F%2Fapic.douyucdn.cn%2Fupload%2Favatar%2Fdefault%2F24_; acf_ct=0; acf_ltkid=71850614; acf_biz=1; acf_stk=9b4120a611d00760; acf_devid=a72ea6ef2f1f6c51a823d212390ce718
|
||||
|
||||
|
||||
|
||||
|
||||
dy_accounts_main=; dy_auth=7febuXzoBCnE7TEoIP28mhEf2OXn6l%2FSwL56eAJA1LYlNzSpDua7PtYlV8gxpxxlPOCFRYwTRw%2BDh6X19MJetWfzOTasWoyu1kxEMg5uitOBAWm5uI%2BqS3M; wan_auth37wan=66e4873d1a6dU7jaNtlupCZ78lHwB7SzAUisHHNHyQlnH3heDOvP4b4CkEPOxy%2FBqT3HGEMra%2FAeflM6D6hfrMpJfXJGoNYwCF08uCnTsYWDiGGHWVE; LTP0=eyJhbGciOiJtZDUiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOlsicGFzc3BvcnQiXSwiY3QiOjAsImN0aW1lIjoxNzgyMjU5OTI5LCJleHAiOjE3OTgwMjc5NDQsImtleSI6ImR5LWp3dC1tZDUiLCJsdGsiOiIwOWJlYWZlZTM2MDBhMjBkIiwibHRraWQiOjU1ODI4NjkxLCJzdWIiOiJsdCIsInVpZCI6NzIyMDUwMDMxfQ.YjVlY2FjNTZkNzIxYjhjMDRjODZhNzE0ZDA3MmQ3OWE; last_login_way=nickname; PHPSESSID=oquhqrc9b6bkfvldj6n7mh9tg2; acf_auth=50c0Hnuwt0o08C%2FaUYAUoiY8QbryaO2fmxkd%2Frn7uktr5WqvmLxNHcpHAcEcgZVmmr29iqA2YTs1adLO%2B4R4NI7Hm8EgLqiKsTw8s152W32rEA9UN7JEL3w; acf_jwt_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJtZDUifQ.eyJ1aWQiOjcyMjA1MDAzMSwiY3QiOjAsInN1YiI6InN0IiwiYXVkIjpbImR5Iiwibm9uZSJdLCJiaXoiOjEsImx0a2lkIjo1NTgyODY5MSwic3RrIjoiMDJhMzM5MjE5YWQxYTdhNSIsImV4cCI6MTc4Mjg2NDcyOSwiaWF0IjoxNzgyMjU5OTI5LCJrZXkiOiJkeS1qd3QtbWQ1In0.YWNlM2FkYTliYjEwMjk5NzdjMDA0Zjc2NGJkNTEwNmQ; acf_dmjwt_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJtZDUifQ.eyJ1aWQiOjcyMjA1MDAzMSwiY3QiOjAsInN1YiI6InN0IiwiYXVkIjpbImRtIiwibm9uZSJdLCJiaXoiOjEsImx0a2lkIjo1NTgyODY5MSwic3RrIjoiMDJhMzM5MjE5YWQxYTdhNSIsImV4cCI6MTc4Mjg2NDcyOSwiaWF0IjoxNzgyMjU5OTI5LCJrZXkiOiJkeS1qd3QtbWQ1In0.ZDljYzlkNTZjNzNhYzMwZjAzNzY5NjQxZmJhM2FmODk; acf_uid=722050031; acf_username=722050031; acf_nickname=%E7%94%A8%E6%88%B76893423879; acf_own_room=0; acf_groupid=1; acf_phonestatus=1; acf_avatar=https%3A%2F%2Fapic.douyucdn.cn%2Fupload%2Favatar%2Fdefault%2F19_; acf_ct=0; acf_ltkid=55828691; acf_biz=1; acf_stk=02a339219ad1a7a5; acf_devid=d5d7050d31074c949bd5394f1241000c; cvl_csrf_token=347aeed3a7974d668de371c1a3213c18
|
||||
dy_accounts_main=; dy_auth=144fZeqHQY%2F5Q50DbCp7oUK%2FI9%2B7tlIme7rNTAzIvKBMRg0dhiiPgJpK%2B3T3OhZrH5UtVwfQW5ZCszgDFbTR9F8BF%2Fc3Ur7ysvx9Uf%2FT1WsIbZUrWW8BnoI; wan_auth37wan=7d824d0ad6c2wGkeajI%2Fsvzj%2FmYcOzG%2FgdI8oWY6Q4%2FoTS%2F%2FC9sTYuuIj6ri6JJBbmgFykBHwsAAFvMVnLnaabjU2t58%2F2jBuNkq6xn%2BgfgUS6cAMaQ; LTP0=eyJhbGciOiJtZDUiLCJ0eXAiOiJKV1QifQ.eyJhdWQiOlsicGFzc3BvcnQiXSwiY3QiOjAsImN0aW1lIjoxNzgyMjYwNjUzLCJleHAiOjE3OTgwMjg2NjcsImtleSI6ImR5LWp3dC1tZDUiLCJsdGsiOiIzOWM3MDRiYzIyZmU5Nzg2IiwibHRraWQiOjQ0MDI1MTUzLCJzdWIiOiJsdCIsInVpZCI6Njc4MTIyNDkxfQ.ZWQ5NmIxOTAyN2IwYjNhMDE4YmVlM2UyZmFjODFmNTk; last_login_way=nickname; PHPSESSID=6ss9t7f10kpujqh7fpp4a0trh3; acf_auth=f204nj4qW9rQLVFTJu7LrwhJqWaioV%2F7iJjzoycsgLLAMCpnRFgFs8vpaa%2B0RQZPrCYkFYJUICxfVD53UylvFXGAtXq6uTPVtv8sNMn%2B0ukwX1CHbQkUJrs; acf_jwt_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJtZDUifQ.eyJ1aWQiOjY3ODEyMjQ5MSwiY3QiOjAsInN1YiI6InN0IiwiYXVkIjpbImR5Iiwibm9uZSJdLCJiaXoiOjEsImx0a2lkIjo0NDAyNTE1Mywic3RrIjoiZjJhOGFmZTc0ZDc0YTdkMCIsImV4cCI6MTc4Mjg2NTQ1MywiaWF0IjoxNzgyMjYwNjUzLCJrZXkiOiJkeS1qd3QtbWQ1In0.MTM0ZWJkYmQxMDJmODdkMGQwZWE3Y2M3OGE4Y2E3OTM; acf_dmjwt_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJtZDUifQ.eyJ1aWQiOjY3ODEyMjQ5MSwiY3QiOjAsInN1YiI6InN0IiwiYXVkIjpbImRtIiwibm9uZSJdLCJiaXoiOjEsImx0a2lkIjo0NDAyNTE1Mywic3RrIjoiZjJhOGFmZTc0ZDc0YTdkMCIsImV4cCI6MTc4Mjg2NTQ1MywiaWF0IjoxNzgyMjYwNjUzLCJrZXkiOiJkeS1qd3QtbWQ1In0.YjUwODJmYThkMmY2NWNmMTNiM2NkNTk4ZTRhMDE0Y2M; acf_uid=678122491; acf_username=678122491; acf_nickname=%E7%94%A8%E6%88%B77808724800; acf_own_room=0; acf_groupid=1; acf_phonestatus=1; acf_avatar=https%3A%2F%2Fapic.douyucdn.cn%2Fupload%2Favatar%2Fdefault%2F19_; acf_ct=0; acf_ltkid=44025153; acf_biz=1; acf_stk=f2a8afe74d74a7d0; acf_devid=6d4bd35a8ad7facc50bc51ab1792558f; cvl_csrf_token=7252fcd623794ba78c7cb6588caee2e9; acf_ccn=40a9800778aca38c01c39ff7d45eabc8
|
||||
|
||||
|
||||
|
||||
========
|
||||
我看了 [对比 ck.txt](/Users/yml/codes/douyu_login_py/对比%20ck.txt),结论是:两组 CK 的核心登录字段都有,但不是同一个账号/同一次登录态;自己跑出来的 CK 少了目标里的 2 个字段,多了 3 个字段。
|
||||
|
||||
**字段差异**
|
||||
|
||||
目标 CK 独有:
|
||||
|
||||
```text
|
||||
cvl_csrf_token
|
||||
acf_ccn
|
||||
```
|
||||
|
||||
自己跑的 CK 独有:
|
||||
|
||||
```text
|
||||
dy_accounts_main=
|
||||
LTP0
|
||||
last_login_way=nickname
|
||||
```
|
||||
|
||||
其中 `dy_accounts_main=` 是空值,实际意义可能不大;`LTP0` 是 passport 侧的长期 token,目标 CK 里没有。
|
||||
|
||||
**相同字段但值不同**
|
||||
|
||||
这些字段两边都有,但值都不一样:
|
||||
|
||||
```text
|
||||
PHPSESSID
|
||||
acf_auth
|
||||
dy_auth
|
||||
wan_auth37wan
|
||||
acf_jwt_token
|
||||
acf_dmjwt_token
|
||||
acf_uid
|
||||
acf_username
|
||||
acf_nickname
|
||||
acf_avatar
|
||||
acf_ltkid
|
||||
acf_stk
|
||||
acf_devid
|
||||
```
|
||||
|
||||
账号信息也不同:
|
||||
|
||||
```text
|
||||
目标 uid: 942416451
|
||||
自己 uid: 1030023740
|
||||
|
||||
目标 nickname: 用户4512197651
|
||||
自己 nickname: 用户4965059115
|
||||
```
|
||||
|
||||
**JWT 载荷对比**
|
||||
|
||||
`acf_jwt_token` / `acf_dmjwt_token` 的结构是一致的,区别主要是账号、`ltkid`、`stk`、签发时间、过期时间:
|
||||
|
||||
```text
|
||||
目标:
|
||||
uid = 942416451
|
||||
ltkid = 69161685
|
||||
stk = 4fd469d169f7734b
|
||||
iat = 2026/6/18 01:39:30
|
||||
exp = 2026/6/25 01:39:29
|
||||
|
||||
自己:
|
||||
uid = 1030023740
|
||||
ltkid = 71850614
|
||||
stk = 9b4120a611d00760
|
||||
iat = 2026/6/24 00:08:50
|
||||
exp = 2026/7/1 00:08:50
|
||||
```
|
||||
|
||||
`acf_jwt_token` 的 `aud` 都是 `["dy", "none"]`,`acf_dmjwt_token` 的 `aud` 都是 `["dm", "none"]`,这部分没问题。
|
||||
|
||||
**关键判断**
|
||||
|
||||
自己跑出来的 CK 看起来是完整登录态,但和目标 CK 的“形态”不完全一样:主要缺 `cvl_csrf_token` 和 `acf_ccn`。如果某些接口依赖 CSRF 或风控相关 cookie,这两个缺失可能会导致请求失败;如果只是普通登录态校验,核心字段已经都有。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user