diff --git a/checkActivity.js b/checkActivity.js index 885344e..9f4692b 100644 --- a/checkActivity.js +++ b/checkActivity.js @@ -1,29 +1,86 @@ // checkActivity.js const axios = require('axios'); const cheerio = require('cheerio'); -const notifier = require('node-notifier'); // 新增桌面通知模块 +const notifier = require('node-notifier'); const url = 'https://www.szhdy.com/activities/default.html?method=activity&id=9'; const checkInterval = 300000; // 5分钟检查一次 -// 设置请求头,模拟浏览器(已包含完整浏览器特征) const headers = { - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36', + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8', - 'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3', + 'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8', 'Connection': 'keep-alive', 'Upgrade-Insecure-Requests': '1', - 'Sec-Fetch-Dest': 'document', - 'Sec-Fetch-Mode': 'navigate', - 'Sec-Fetch-Site': 'none', - 'Sec-Fetch-User': '?1' }; +// Cookie 管理 +let cookieJar = new Map(); +let cookieExpiry = 0; + +function mergeCookiesFromHeaders(setCookieHeaders) { + for (const header of setCookieHeaders) { + const pair = header.split(';')[0]; + const eqIdx = pair.indexOf('='); + if (eqIdx > 0) { + cookieJar.set(pair.substring(0, eqIdx).trim(), pair.substring(eqIdx + 1).trim()); + } + } +} + +function getCookieString() { + return Array.from(cookieJar.entries()).map(([k, v]) => `${k}=${v}`).join('; '); +} + +async function getValidCookies() { + if (cookieJar.size > 0 && Date.now() < cookieExpiry) { + return getCookieString(); + } + console.log('[Cookie] 正在获取新的 Cookie...'); + cookieJar.clear(); + // 第一次请求拿 CDN Cookie(会返回 403,这是预期行为) + const res = await axios.get(url, { + headers, + maxRedirects: 0, + validateStatus: () => true, // 允许非 2xx 状态码 + }); + const setCookies = res.headers['set-cookie'] || []; + mergeCookiesFromHeaders(setCookies); + cookieExpiry = Date.now() + 3600 * 1000; + console.log('[Cookie] 获取成功:', getCookieString()); + return getCookieString(); +} async function checkActivity() { try { - const response = await axios.get(url, { headers }); + const cookies = await getValidCookies(); + const response = await axios.get(url, { + headers: { ...headers, Cookie: cookies }, + }); const html = response.data; + + // 如果响应内容过短,Cookie 可能失效,刷新重试 + if (typeof html === 'string' && html.length < 1000) { + console.log('[Cookie] 响应内容过短,刷新 Cookie 重试...'); + cookieJar.clear(); + cookieExpiry = 0; + const retryCookies = await getValidCookies(); + const retryRes = await axios.get(url, { + headers: { ...headers, Cookie: retryCookies }, + }); + mergeCookiesFromHeaders(retryRes.headers['set-cookie'] || []); + return parseAndCheck(retryRes.data); + } + + // 合并新返回的 Cookie + mergeCookiesFromHeaders(response.headers['set-cookie'] || []); + return parseAndCheck(html); + } catch (error) { + console.error(`请求失败: ${error.message}`); + } +} + +function parseAndCheck(html) { const $ = cheerio.load(html); // 限定在活动主容器内检测,避免扫描其他区域 @@ -184,9 +241,6 @@ async function checkActivity() { } else { console.log(`[${new Date().toLocaleString()}] 暂未上架,继续监控...`); } - } catch (error) { - console.error(`请求失败: ${error.message}`); - } } // 立即执行一次 diff --git a/monitor-server.js b/monitor-server.js index dd66441..ac460de 100644 --- a/monitor-server.js +++ b/monitor-server.js @@ -17,30 +17,43 @@ const REQUEST_HEADERS = { 'Upgrade-Insecure-Requests': '1', }; -// 存储 Cookie -let cachedCookies = ''; +// 存储 Cookie(key-value Map,支持合并更新) +let cookieJar = new Map(); let cookieExpiry = 0; -// 从 set-cookie 响应头提取 Cookie -function extractCookies(response) { +// 从 set-cookie 响应头提取 Cookie,合并到 cookieJar +function mergeCookies(response) { const setCookieHeaders = response.headers.getSetCookie?.() || []; - const cookies = setCookieHeaders.map(c => c.split(';')[0]).join('; '); - return cookies; + for (const header of setCookieHeaders) { + const pair = header.split(';')[0]; // 取 name=value 部分 + const eqIdx = pair.indexOf('='); + if (eqIdx > 0) { + const name = pair.substring(0, eqIdx).trim(); + const value = pair.substring(eqIdx + 1).trim(); + cookieJar.set(name, value); + } + } +} + +// 将 cookieJar 序列化为请求头格式 +function getCookieString() { + return Array.from(cookieJar.entries()).map(([k, v]) => `${k}=${v}`).join('; '); } // 获取有效 Cookie(过期或为空时重新获取) async function getValidCookies() { - if (cachedCookies && Date.now() < cookieExpiry) { - return cachedCookies; + if (cookieJar.size > 0 && Date.now() < cookieExpiry) { + return getCookieString(); } console.log('[Cookie] 正在获取新的 Cookie...'); + cookieJar.clear(); const response = await fetch(ACTIVITY_URL, { headers: REQUEST_HEADERS, redirect: 'manual' }); - cachedCookies = extractCookies(response); - // Cookie 有效期设为 1 小时(服务器 max-age=86400,保守取 1 小时) + mergeCookies(response); + // CDN Cookie 有效期 2 小时,保守取 1 小时刷新 cookieExpiry = Date.now() + 3600 * 1000; - console.log('[Cookie] 获取成功:', cachedCookies); - return cachedCookies; + console.log('[Cookie] 获取成功:', getCookieString()); + return getCookieString(); } app.get('/api/activity', async (req, res) => { @@ -54,11 +67,13 @@ app.get('/api/activity', async (req, res) => { }); const html = await response.text(); + // 合并第二次请求返回的 Cookie(如 PHPSESSID) + mergeCookies(response); // 如果返回内容过短,可能 Cookie 失效,清除缓存并重试一次 if (html.length < 1000) { console.log('[Cookie] 响应内容过短,尝试刷新 Cookie 重试...'); - cachedCookies = ''; + cookieJar.clear(); cookieExpiry = 0; const newCookies = await getValidCookies(); const retryResponse = await fetch(ACTIVITY_URL, { @@ -68,22 +83,10 @@ app.get('/api/activity', async (req, res) => { } }); const retryHtml = await retryResponse.text(); - // 更新重试后的 Cookie - const retryCookies = extractCookies(retryResponse); - if (retryCookies) { - cachedCookies = retryCookies; - cookieExpiry = Date.now() + 3600 * 1000; - } + mergeCookies(retryResponse); return res.json({ success: true, html: retryHtml }); } - // 更新响应中的新 Cookie - const newCookies = extractCookies(response); - if (newCookies) { - cachedCookies = newCookies; - cookieExpiry = Date.now() + 3600 * 1000; - } - res.json({ success: true, html }); } catch (error) { res.status(500).json({ success: false, error: error.message }); diff --git a/public/index.html b/public/index.html index 0d5e0f1..11e940f 100644 --- a/public/index.html +++ b/public/index.html @@ -521,6 +521,7 @@ +