Просмотр исходного кода

feat: enhance proxy handling and upload monitoring in Weixin publisher

- Added detailed logging for proxy payload keys and request parameters in the Shenlong proxy resolution.
- Improved region code formatting logic to ensure compatibility with the Shenlong API.
- Implemented network request monitoring for upload-related domains in the Weixin publisher, capturing request and response statuses.
- Enhanced progress reporting during video uploads, including periodic screenshots for troubleshooting.

These changes improve the robustness and observability of the publishing process.
Ethanfly 1 день назад
Родитель
Сommit
664ea953e3
3 измененных файлов с 74 добавлено и 8 удалено
  1. 10 3
      server/python/app.py
  2. 61 2
      server/python/platforms/weixin.py
  3. 3 3
      server/src/services/PublishService.ts

+ 10 - 3
server/python/app.py

@@ -327,6 +327,7 @@ def _resolve_shenlong_proxy(proxy_payload: dict, platform: str = None) -> dict:
     test_url = 'http://myip.ipip.net'
     city = str(proxy_payload.get('city') or '').strip()
     region_code = str(proxy_payload.get('regionCode') or '').strip()
+    print(f"[Proxy] 入参 proxy_payload keys: {list(proxy_payload.keys())}, regionCode={region_code!r}", flush=True)
     api_url = str(proxy_payload.get('apiUrl') or '').strip()
     product_key = str(proxy_payload.get('productKey') or '').strip()
     signature = str(proxy_payload.get('signature') or '').strip()
@@ -341,10 +342,9 @@ def _resolve_shenlong_proxy(proxy_payload: dict, platform: str = None) -> dict:
     if not signature:
         raise Exception('缺少神龙签名')
 
+    # 格式化地区编码:神龙 API 的 area 参数支持 6 位编码,省级(0000)、地级(00) 均保留传递
     if region_code and region_code.isdigit() and len(region_code) == 6:
-        if region_code.endswith('0000'):
-            region_code = ''
-        elif not region_code.endswith('00'):
+        if not region_code.endswith('00'):
             region_code = region_code[:4] + '00'
 
     cache_key = ''
@@ -371,6 +371,13 @@ def _resolve_shenlong_proxy(proxy_payload: dict, platform: str = None) -> dict:
     if isp:
         params['isp'] = isp
 
+    # 日志:打印获取代理 IP 的 URL 和参数
+    from urllib.parse import urlencode
+    full_url = f"{request_url}?{urlencode(params)}"
+    print(f"[Proxy] 获取代理IP URL: {request_url}", flush=True)
+    print(f"[Proxy] 获取代理IP 参数: {params}", flush=True)
+    print(f"[Proxy] 完整请求URL: {full_url}", flush=True)
+
     payload = None
     session = requests.Session()
     session.trust_env = False

+ 61 - 2
server/python/platforms/weixin.py

@@ -369,7 +369,19 @@ class WeixinPublisher(BasePublisher):
         if proxy and proxy.get("server"):
             # 启用上传 bypass 时:仅对上传 CDN 直连,其余仍走代理
             if WEIXIN_UPLOAD_BYPASS_PROXY:
-                bypass = "findeross.weixin.qq.com,upload.weixin.qq.com,*.cos.qq.com,*.myqcloud.com,*.tencentcloudapi.com"
+                bypass = ",".join([
+                    "findeross.weixin.qq.com",
+                    "upload.weixin.qq.com",
+                    "finder.video.qq.com",
+                    "szextshort.weixin.qq.com",
+                    "mp.weixin.qq.com",
+                    "*.cos.qq.com",
+                    "*.cos.ap-*.myqcloud.com",
+                    "*.myqcloud.com",
+                    "*.tencentcloudapi.com",
+                    "*.video.qq.com",
+                    "*.cdn-go.cn",
+                ])
                 proxy = dict(proxy)
                 proxy["bypass"] = bypass
                 print(
@@ -1225,6 +1237,42 @@ class WeixinPublisher(BasePublisher):
 
         self.report_progress(30, "等待视频上传完成...")
 
+        # 监控网络请求,捕捉上传相关域名和状态
+        _upload_domains_seen = set()
+        def _on_request(req):
+            url = req.url
+            if any(kw in url for kw in ["upload", "cos.", "myqcloud", "finder", "video", "media"]):
+                from urllib.parse import urlparse
+                domain = urlparse(url).netloc
+                method = req.method
+                if domain not in _upload_domains_seen:
+                    _upload_domains_seen.add(domain)
+                    print(f"[{self.platform_name}] ⭐ 上传相关请求: {method} {domain} ({url[:120]})", flush=True)
+
+        def _on_response(resp):
+            url = resp.url
+            if any(kw in url for kw in ["upload", "cos.", "myqcloud", "finder", "video", "media"]):
+                from urllib.parse import urlparse
+                domain = urlparse(url).netloc
+                status = resp.status
+                if status >= 400 or status == 0:
+                    print(f"[{self.platform_name}] ❌ 上传响应失败: {status} {domain} ({url[:120]})", flush=True)
+                else:
+                    print(f"[{self.platform_name}] ✅ 上传响应: {status} {domain}", flush=True)
+
+        def _on_request_failed(req):
+            url = req.url
+            if any(kw in url for kw in ["upload", "cos.", "myqcloud", "finder", "video", "media"]):
+                from urllib.parse import urlparse
+                domain = urlparse(url).netloc
+                failure = req.failure
+                print(f"[{self.platform_name}] ❌ 上传请求失败: {domain} failure={failure} ({url[:120]})", flush=True)
+
+        self.page.on("request", _on_request)
+        self.page.on("response", _on_response)
+        self.page.on("requestfailed", _on_request_failed)
+        print(f"[{self.platform_name}] 已启用上传网络请求监控", flush=True)
+
         # 代理模式下增加重试次数和总时长,应对「网络出错」等不稳定情况
         using_proxy = isinstance(
             getattr(self, "proxy_config", None), dict
@@ -1243,10 +1291,21 @@ class WeixinPublisher(BasePublisher):
             try:
                 # 每 30 秒打印一次进度,避免“卡住”的错觉
                 if i > 0 and i % 10 == 0:
+                    elapsed_s = i * 3
                     print(
-                        f"[{self.platform_name}] 仍在等待上传完成... ({i * 3}s)",
+                        f"[{self.platform_name}] 仍在等待上传完成... ({elapsed_s}s)",
                         flush=True,
                     )
+                    # 每 60 秒保存一次截图,方便排查上传卡住问题
+                    if i % 20 == 0:
+                        try:
+                            ss_path = await self.save_screenshot_to_file(
+                                filename_prefix=f"weixin_upload_waiting_{elapsed_s}s"
+                            )
+                            if ss_path:
+                                print(f"[{self.platform_name}] 等待中截图已保存: {ss_path}", flush=True)
+                        except Exception as ss_err:
+                            print(f"[{self.platform_name}] 等待中截图失败: {ss_err}", flush=True)
 
                 # 尝试多种选择器定位“发表”按钮(页面结构可能变化)
                 publish_btn = None

+ 3 - 3
server/src/services/PublishService.ts

@@ -795,9 +795,9 @@ export class PublishService {
 
     const rawRegionCode = publishProxy.regionCode ? String(publishProxy.regionCode).trim() : '';
     let regionCode: string | undefined = rawRegionCode || undefined;
-    if (regionCode && /^\d{6}$/.test(regionCode)) {
-      if (regionCode.endsWith('0000')) regionCode = undefined;
-      else if (!regionCode.endsWith('00')) regionCode = `${regionCode.slice(0, 4)}00`;
+    // 格式化地区编码:神龙 API 支持 6 位编码,省级(0000)、地级(00) 均保留传递
+    if (regionCode && /^\d{6}$/.test(regionCode) && !regionCode.endsWith('00')) {
+      regionCode = `${regionCode.slice(0, 4)}00`;
     }
 
     return {