diff --git a/aliyun-sync/COMMANDS.md b/aliyun-sync/COMMANDS.md index bfd24a5..0979c21 100644 --- a/aliyun-sync/COMMANDS.md +++ b/aliyun-sync/COMMANDS.md @@ -101,8 +101,10 @@ ALIYUN_APS_SCHEDULE_MODE=incremental ```env ALIYUN_APS_BASE_URL=https://aps.aliyun.com ALIYUN_APS_HEADLESS=false +ALIYUN_APS_BROWSER_MODE=launch ALIYUN_APS_BROWSER_CHANNEL= ALIYUN_APS_BROWSER_EXECUTABLE_PATH= +ALIYUN_APS_CDP_URL=http://127.0.0.1:9222 ALIYUN_APS_TIMEZONE=Asia/Shanghai ALIYUN_APS_CRON=0 6 * * * ALIYUN_APS_SCHEDULE_MODE=incremental @@ -137,11 +139,26 @@ ALIYUN_APS_CLOSE_BROWSER=true 浏览器选择规则: +- `ALIYUN_APS_BROWSER_MODE=launch`:Playwright 自己启动浏览器 +- `ALIYUN_APS_BROWSER_MODE=cdp`:附着到你手动打开的浏览器 - 两项都留空:使用 Playwright 自带 Chromium - `ALIYUN_APS_BROWSER_CHANNEL=chrome`:使用 Chrome - `ALIYUN_APS_BROWSER_CHANNEL=msedge`:使用 Edge - `ALIYUN_APS_BROWSER_EXECUTABLE_PATH=...`:使用指定浏览器路径 +如果要自己手动打开 Chrome 并过验证码,可先执行: + +```powershell +chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\temp\aps-manual-profile" +``` + +然后 `.env` 配置: + +```env +ALIYUN_APS_BROWSER_MODE=cdp +ALIYUN_APS_CDP_URL=http://127.0.0.1:9222 +``` + ## 11. 推荐执行顺序 ### 首次初始化 diff --git a/aliyun-sync/aliyun-aps-sync/.env b/aliyun-sync/aliyun-aps-sync/.env index a893c7c..ef7fb5f 100644 --- a/aliyun-sync/aliyun-aps-sync/.env +++ b/aliyun-sync/aliyun-aps-sync/.env @@ -1,7 +1,9 @@ ALIYUN_APS_BASE_URL=https://aps.aliyun.com ALIYUN_APS_HEADLESS=false -ALIYUN_APS_BROWSER_CHANNEL=msedge +ALIYUN_APS_BROWSER_MODE=cdp +ALIYUN_APS_BROWSER_CHANNEL= ALIYUN_APS_BROWSER_EXECUTABLE_PATH= +ALIYUN_APS_CDP_URL=http://127.0.0.1:9222 ALIYUN_APS_TIMEZONE=Asia/Shanghai ALIYUN_APS_CRON=0 6 * * * ALIYUN_APS_ORDER_START_DATE=2023-01-01 @@ -26,9 +28,6 @@ ALIYUN_APS_NOTIFY_EMAIL=1416431931@qq.com # 浏览器关闭策略: true=执行完关闭(默认), false=保持浏览器不关闭 ALIYUN_APS_CLOSE_BROWSER=true -# Python 入库脚本路径 -ALIYUN_APS_DB_SYNC_SCRIPT=../aps-aliyun-sync/aps_db_sync.py - # 全量同步: true=从起始日期遍历所有月份(默认), false=增量(订单查前一天,账单查当月) ALIYUN_APS_FULL_SYNC=true @@ -38,4 +37,4 @@ ALIYUN_APS_DB_USER=ray ALIYUN_APS_DB_PASSWORD=GV0C$ErephgQO7RQc7b6 ALIYUN_APS_DB_NAME=crm-prod ALIYUN_APS_DB_CHARSET=utf8mb4 -ALIYUN_APS_DB_CONNECTION_LIMIT=5 \ No newline at end of file +ALIYUN_APS_DB_CONNECTION_LIMIT=5 diff --git a/aliyun-sync/aliyun-aps-sync/.env.example b/aliyun-sync/aliyun-aps-sync/.env.example index dccfd35..28b2ed5 100644 --- a/aliyun-sync/aliyun-aps-sync/.env.example +++ b/aliyun-sync/aliyun-aps-sync/.env.example @@ -1,7 +1,9 @@ ALIYUN_APS_BASE_URL=https://aps.aliyun.com ALIYUN_APS_HEADLESS=false +ALIYUN_APS_BROWSER_MODE=launch ALIYUN_APS_BROWSER_CHANNEL= ALIYUN_APS_BROWSER_EXECUTABLE_PATH= +ALIYUN_APS_CDP_URL=http://127.0.0.1:9222 ALIYUN_APS_TIMEZONE=Asia/Shanghai ALIYUN_APS_CRON=0 6 * * * ALIYUN_APS_SCHEDULE_MODE=incremental diff --git a/aliyun-sync/aliyun-aps-sync/README.md b/aliyun-sync/aliyun-aps-sync/README.md index d8fb171..e2ba4ef 100644 --- a/aliyun-sync/aliyun-aps-sync/README.md +++ b/aliyun-sync/aliyun-aps-sync/README.md @@ -153,17 +153,50 @@ ALIYUN_APS_DB_CONNECTION_LIMIT=5 可选配置: ```env +ALIYUN_APS_BROWSER_MODE=launch ALIYUN_APS_BROWSER_CHANNEL= ALIYUN_APS_BROWSER_EXECUTABLE_PATH= +ALIYUN_APS_CDP_URL=http://127.0.0.1:9222 ``` 说明: +- `ALIYUN_APS_BROWSER_MODE=launch`:由 Playwright 自己启动浏览器。 +- `ALIYUN_APS_BROWSER_MODE=cdp`:附着到你手动打开的 Chrome/Edge。 - 两项都留空:使用 Playwright 自带 Chromium。 - `ALIYUN_APS_BROWSER_CHANNEL=chrome`:使用本机 Chrome。 - `ALIYUN_APS_BROWSER_CHANNEL=msedge`:使用本机 Edge。 - `ALIYUN_APS_BROWSER_EXECUTABLE_PATH=...`:指定本地浏览器可执行文件路径。 +### 手动打开 Chrome 后再让脚本附着 + +如果阿里云风控要求你手动过滑块,可以改成: + +```env +ALIYUN_APS_BROWSER_MODE=cdp +ALIYUN_APS_CDP_URL=http://127.0.0.1:9222 +``` + +然后你手动启动浏览器: + +```powershell +chrome.exe --remote-debugging-port=9222 --user-data-dir="C:\temp\aps-manual-profile" +``` + +在浏览器里手动登录并过验证码后,再执行: + +```bash +npm run sync +``` + +或: + +```bash +npm run bills -- --resume +``` + +附着模式下脚本不会自动关闭你手动打开的浏览器。 + ## 邮件告警 任意运行异常会尝试: diff --git a/aliyun-sync/aliyun-aps-sync/src/config.js b/aliyun-sync/aliyun-aps-sync/src/config.js index ba56b19..96e56a7 100644 --- a/aliyun-sync/aliyun-aps-sync/src/config.js +++ b/aliyun-sync/aliyun-aps-sync/src/config.js @@ -20,8 +20,10 @@ export const config = { rootDir, baseUrl: process.env.ALIYUN_APS_BASE_URL || 'https://aps.aliyun.com', headless: toBool(process.env.ALIYUN_APS_HEADLESS, false), + browserMode: (process.env.ALIYUN_APS_BROWSER_MODE || 'launch').trim().toLowerCase(), browserChannel: (process.env.ALIYUN_APS_BROWSER_CHANNEL || '').trim(), browserExecutablePath: (process.env.ALIYUN_APS_BROWSER_EXECUTABLE_PATH || '').trim(), + cdpUrl: (process.env.ALIYUN_APS_CDP_URL || 'http://127.0.0.1:9222').trim(), timezone: process.env.ALIYUN_APS_TIMEZONE || 'Asia/Shanghai', cron: process.env.ALIYUN_APS_CRON || '0 6 * * *', orderStartDate: process.env.ALIYUN_APS_ORDER_START_DATE || '2024-01-01', diff --git a/aliyun-sync/aliyun-aps-sync/src/sync.js b/aliyun-sync/aliyun-aps-sync/src/sync.js index cf25823..58a1f64 100644 --- a/aliyun-sync/aliyun-aps-sync/src/sync.js +++ b/aliyun-sync/aliyun-aps-sync/src/sync.js @@ -33,6 +33,8 @@ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); let _context = null; let _runtimeController = null; +let _browser = null; +let _isAttachedBrowser = false; const AUTH_PAGE_KEYWORDS = [ 'RAM 用户登录', @@ -45,6 +47,10 @@ const AUTH_PAGE_KEYWORDS = [ async function closeContextIfNeeded() { if (!_context) return; + if (_isAttachedBrowser) { + _context = null; + return; + } await _context.close(); _context = null; } @@ -161,6 +167,20 @@ function clearStaleBrowserProfileLocks() { async function getContext() { if (_context) return _context; + if (config.browserMode === 'cdp') { + try { + _browser = await chromium.connectOverCDP(config.cdpUrl); + _isAttachedBrowser = true; + const contexts = _browser.contexts(); + _context = contexts[0] || await _browser.newContext(); + console.log(`[CDP] 已附着到手动浏览器: ${config.cdpUrl}`); + return _context; + } catch (error) { + throw new Error(`无法通过 CDP 连接到手动浏览器(${config.cdpUrl})。请先手动启动 Chrome 并开启远程调试端口。原始错误: ${error.message}`); + } + } + + _isAttachedBrowser = false; clearStaleBrowserProfileLocks(); const launchOptions = { headless: config.headless,