From 9efe6226498c939c906862e7e420ecd5f3d8453c Mon Sep 17 00:00:00 2001
From: zhinianboke <115088296+zhinianboke@users.noreply.github.com>
Date: Wed, 20 Aug 2025 14:54:05 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96token=E5=88=B7=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
XianyuAutoAsync.py | 130 +++++++++++++++++++++++++++++++++++----------
global_config.yml | 4 +-
2 files changed, 104 insertions(+), 30 deletions(-)
diff --git a/XianyuAutoAsync.py b/XianyuAutoAsync.py
index 046215c..2df9811 100644
--- a/XianyuAutoAsync.py
+++ b/XianyuAutoAsync.py
@@ -197,11 +197,13 @@ class XianyuLive:
# Cookie刷新定时任务
self.cookie_refresh_task = None
- self.cookie_refresh_interval = 600 # 1小时 = 3600秒
+ self.cookie_refresh_interval = 1200 # 1小时 = 3600秒
self.last_cookie_refresh_time = 0
self.cookie_refresh_running = False # 防止重复执行Cookie刷新
self.cookie_refresh_enabled = True # 是否启用Cookie刷新功能
+
+
# WebSocket连接监控
self.connection_failures = 0 # 连续连接失败次数
self.max_connection_failures = 5 # 最大连续失败次数
@@ -676,10 +678,13 @@ class XianyuLive:
"""刷新token"""
try:
logger.info(f"【{self.cookie_id}】开始刷新token...")
+ # 生成更精确的时间戳
+ timestamp = str(int(time.time() * 1000))
+
params = {
'jsv': '2.7.2',
'appKey': '34839810',
- 't': str(int(time.time()) * 1000),
+ 't': timestamp,
'sign': '',
'v': '1.0',
'type': 'originaljson',
@@ -688,7 +693,13 @@ class XianyuLive:
'timeout': '20000',
'api': 'mtop.taobao.idlemessage.pc.login.token',
'sessionOption': 'AutoLoginOnly',
+ 'dangerouslySetWindvaneParams': '%5Bobject%20Object%5D',
+ 'smToken': 'token',
+ 'queryToken': 'sm',
+ 'sm': 'sm',
'spm_cnt': 'a21ybx.im.0.0',
+ 'spm_pre': 'a21ybx.home.sidebar.1.4c053da6vYwnmf',
+ 'log_id': '4c053da6vYwnmf'
}
data_val = '{"appKey":"444e9908a51d1cb236a27862abc769c9","deviceId":"' + self.device_id + '"}'
data = {
@@ -702,9 +713,25 @@ class XianyuLive:
sign = generate_sign(params['t'], token, data_val)
params['sign'] = sign
- # 发送请求
- headers = DEFAULT_HEADERS.copy()
- headers['cookie'] = self.cookies_str
+ # 发送请求 - 使用与浏览器完全一致的请求头
+ headers = {
+ 'accept': 'application/json',
+ 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
+ 'cache-control': 'no-cache',
+ 'content-type': 'application/x-www-form-urlencoded',
+ 'pragma': 'no-cache',
+ 'priority': 'u=1, i',
+ 'sec-ch-ua': '"Not;A=Brand";v="99", "Google Chrome";v="139", "Chromium";v="139"',
+ 'sec-ch-ua-mobile': '?0',
+ 'sec-ch-ua-platform': '"Windows"',
+ 'sec-fetch-dest': 'empty',
+ 'sec-fetch-mode': 'cors',
+ 'sec-fetch-site': 'same-site',
+ 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36',
+ 'referer': 'https://www.goofish.com/',
+ 'origin': 'https://www.goofish.com',
+ 'cookie': self.cookies_str
+ }
async with aiohttp.ClientSession() as session:
async with session.post(
@@ -3153,6 +3180,7 @@ class XianyuLive:
if not self.current_token or (time.time() - self.last_token_refresh_time) >= self.token_refresh_interval:
logger.info(f"【{self.cookie_id}】获取初始token...")
token_refresh_attempted = True
+
await self.refresh_token()
if not self.current_token:
@@ -3319,6 +3347,8 @@ class XianyuLive:
async def _execute_cookie_refresh(self, current_time):
"""独立执行Cookie刷新任务,避免阻塞主循环"""
+
+
# 设置运行状态,防止重复执行
self.cookie_refresh_running = True
@@ -3369,18 +3399,26 @@ class XianyuLive:
# 清除运行状态
self.cookie_refresh_running = False
+
+
def enable_cookie_refresh(self, enabled: bool = True):
"""启用或禁用Cookie刷新功能"""
self.cookie_refresh_enabled = enabled
status = "启用" if enabled else "禁用"
logger.info(f"【{self.cookie_id}】Cookie刷新功能已{status}")
- def disable_cookie_refresh(self):
- """禁用Cookie刷新功能"""
- self.enable_cookie_refresh(False)
+
+
+
+
+
+
+
async def _refresh_cookies_via_browser(self):
"""通过浏览器访问指定页面刷新Cookie"""
+
+
playwright = None
browser = None
try:
@@ -3401,25 +3439,18 @@ class XianyuLive:
class DummyChildWatcher:
def __enter__(self):
return self
-
def __exit__(self, *args):
pass
-
def is_active(self):
return True
-
def add_child_handler(self, *args, **kwargs):
pass
-
def remove_child_handler(self, *args, **kwargs):
pass
-
def attach_loop(self, *args, **kwargs):
pass
-
def close(self):
pass
-
def __del__(self):
pass
@@ -3497,16 +3528,21 @@ class XianyuLive:
'--use-mock-keychain'
])
+ # Cookie刷新模式使用无头浏览器
browser = await playwright.chromium.launch(
headless=True,
args=browser_args
)
# 创建浏览器上下文
- context = await browser.new_context(
- viewport={'width': 1920, 'height': 1080},
- user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36'
- )
+ context_options = {
+ 'user_agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36'
+ }
+
+ # 使用标准窗口大小
+ context_options['viewport'] = {'width': 1920, 'height': 1080}
+
+ context = await browser.new_context(**context_options)
# 设置当前Cookie
cookies = []
@@ -3526,28 +3562,66 @@ class XianyuLive:
# 创建页面
page = await context.new_page()
+ # 等待页面准备
+ await asyncio.sleep(0.1)
+
# 访问指定页面
target_url = "https://www.goofish.com/im?spm=a21ybx.home.sidebar.1.4c053da6vYwnmf"
logger.info(f"【{self.cookie_id}】访问页面: {target_url}")
- # 进一步缩短超时时间,减少对WebSocket的影响
- await page.goto(target_url, wait_until='domcontentloaded', timeout=10000)
+ # 使用更灵活的页面访问策略
+ try:
+ # 首先尝试较短超时
+ await page.goto(target_url, wait_until='domcontentloaded', timeout=15000)
+ logger.info(f"【{self.cookie_id}】页面访问成功")
+ except Exception as e:
+ if 'timeout' in str(e).lower():
+ logger.warning(f"【{self.cookie_id}】页面访问超时,尝试降级策略...")
+ try:
+ # 降级策略:只等待基本加载
+ await page.goto(target_url, wait_until='load', timeout=20000)
+ logger.info(f"【{self.cookie_id}】页面访问成功(降级策略)")
+ except Exception as e2:
+ logger.warning(f"【{self.cookie_id}】降级策略也失败,尝试最基本访问...")
+ # 最后尝试:不等待任何加载完成
+ await page.goto(target_url, timeout=25000)
+ logger.info(f"【{self.cookie_id}】页面访问成功(最基本策略)")
+ else:
+ raise e
- # 最小化等待时间
- logger.info(f"【{self.cookie_id}】页面加载完成,快速刷新...")
+ # Cookie刷新模式:执行两次刷新
+ logger.info(f"【{self.cookie_id}】页面加载完成,开始刷新...")
await asyncio.sleep(1)
- # 第一次刷新 - 缩短超时时间
+ # 第一次刷新 - 带重试机制
logger.info(f"【{self.cookie_id}】执行第一次刷新...")
- await page.reload(wait_until='domcontentloaded', timeout=8000)
+ try:
+ await page.reload(wait_until='domcontentloaded', timeout=12000)
+ logger.info(f"【{self.cookie_id}】第一次刷新成功")
+ except Exception as e:
+ if 'timeout' in str(e).lower():
+ logger.warning(f"【{self.cookie_id}】第一次刷新超时,使用降级策略...")
+ await page.reload(wait_until='load', timeout=15000)
+ logger.info(f"【{self.cookie_id}】第一次刷新成功(降级策略)")
+ else:
+ raise e
await asyncio.sleep(1)
- # 第二次刷新 - 缩短超时时间
+ # 第二次刷新 - 带重试机制
logger.info(f"【{self.cookie_id}】执行第二次刷新...")
- await page.reload(wait_until='domcontentloaded', timeout=8000)
+ try:
+ await page.reload(wait_until='domcontentloaded', timeout=12000)
+ logger.info(f"【{self.cookie_id}】第二次刷新成功")
+ except Exception as e:
+ if 'timeout' in str(e).lower():
+ logger.warning(f"【{self.cookie_id}】第二次刷新超时,使用降级策略...")
+ await page.reload(wait_until='load', timeout=15000)
+ logger.info(f"【{self.cookie_id}】第二次刷新成功(降级策略)")
+ else:
+ raise e
await asyncio.sleep(1)
- # 获取更新后的Cookie
+ # Cookie刷新模式:正常更新Cookie
logger.info(f"【{self.cookie_id}】获取更新后的Cookie...")
updated_cookies = await context.cookies()
diff --git a/global_config.yml b/global_config.yml
index e3f9217..63c812b 100644
--- a/global_config.yml
+++ b/global_config.yml
@@ -45,7 +45,7 @@ DEFAULT_HEADERS:
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,
like Gecko) Chrome/133.0.0.0 Safari/537.36
HEARTBEAT_INTERVAL: 15
-HEARTBEAT_TIMEOUT: 5
+HEARTBEAT_TIMEOUT: 20
LOG_CONFIG:
compression: zip
format: '{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8}
@@ -58,7 +58,7 @@ MANUAL_MODE:
timeout: 3600
toggle_keywords: []
MESSAGE_EXPIRE_TIME: 300000
-TOKEN_REFRESH_INTERVAL: 72000 # 从3600秒(1小时)增加到18000秒(20小时)
+TOKEN_REFRESH_INTERVAL: 72000 # 从3600秒(1小时)增加到72000秒(20小时)
TOKEN_RETRY_INTERVAL: 7200 # 从300秒(5分钟)增加到7200秒(2小时)
WEBSOCKET_HEADERS:
Accept-Encoding: gzip, deflate, br, zstd