cvl_csrf_token 是有了, 但是 acf_ccn 还没有

This commit is contained in:
yml2213
2026-06-24 08:15:15 +08:00
parent 4813eb039d
commit ae92cd2441
2 changed files with 164 additions and 1 deletions
+58 -1
View File
@@ -54,6 +54,8 @@ class DouyuLogin:
VERIFY_API = "https://passport.douyu.com/wgapi/member/passport/remotelogin/verify"
LOGIN_CALLBACK_API = "https://www.douyu.com/api/passport/login"
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"
LOGIN_REFERER = (
"https://passport.douyu.com/index/login?"
"passport_reg_callback=PASSPORT_REG_SUCCESS_CALLBACK&"
@@ -732,7 +734,62 @@ class DouyuLogin:
except Exception as e:
logger.warning(f"WebLogin请求失败(不影响登录): {e}")
# 收集所有Cookie
# 登录成功后访问斗鱼 Web CSRF 接口,补齐 cvl_csrf_token;响应里的 acf_ccn 也会进入 session cookie jar。
self._generate_csrf_cookie()
return self._format_cookie_string()
def _generate_csrf_cookie(self) -> str:
"""
访问斗鱼 generateCsrf 接口,从 Set-Cookie 中同步 cvl_csrf_token。
requests.Session 会自动接收响应中的 Set-Cookie,所以这里不只保存
cvl_csrf_token;接口额外下发的 acf_ccn 等 Cookie 也会保留到最终 CK。
"""
logger.info("补齐CSRF Cookie...")
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.6,en;q=0.5',
'Origin': 'https://www.douyu.com',
'Referer': self.CSRF_REFERER,
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
# 覆盖登录接口的默认表单头,尽量贴近浏览器抓包。
'Content-Type': None,
'X-Requested-With': None,
}
response = self._request('post', self.CSRF_API, headers=headers)
response.raise_for_status()
body = response.text.strip()
if not body:
raise ValueError("生成CSRF失败: 响应为空")
try:
payload = response.json()
except json.JSONDecodeError as exc:
preview = body[:200].replace("\n", "\\n")
raise ValueError(f"生成CSRF失败: 响应不是有效 JSON: {preview}") from exc
if payload.get('error') != 0:
raise ValueError(f"生成CSRF失败: {payload.get('msg', '未知错误')}")
cookies = self.session.cookies.get_dict()
csrf_token = cookies.get('cvl_csrf_token', '')
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 _format_cookie_string(self) -> str:
"""把当前 session 中的 Cookie 格式化为可导出的 CK 字符串。"""
cookies = self.session.cookies.get_dict()
# 格式化Cookie字符串