From 574fb663c24754ca07b24a41babecf6f242fdad7 Mon Sep 17 00:00:00 2001 From: pseudoyu Date: Sat, 28 Mar 2026 18:48:32 +0800 Subject: [PATCH] fix(route/qiche365): use set cookie to fix fetch failed issue --- lib/routes/qiche365/recall.ts | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/lib/routes/qiche365/recall.ts b/lib/routes/qiche365/recall.ts index 397d44782..d3f06ce88 100644 --- a/lib/routes/qiche365/recall.ts +++ b/lib/routes/qiche365/recall.ts @@ -7,6 +7,8 @@ import timezone from '@/utils/timezone'; const baseUrl = 'https://www.qiche365.org.cn'; +const userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'; + export const route: Route = { path: '/recall/:channel', name: '汽车召回', @@ -16,6 +18,9 @@ export const route: Route = { | ------------ | ------------ | ------------ | ------------ | | 1 | 2 | 3 | 4 |`, categories: ['government'], + features: { + antiCrawler: true, + }, maintainers: ['huanfe1'], handler, url: 'qiche365.org.cn/index/recall/index.html', @@ -23,12 +28,26 @@ export const route: Route = { async function handler(ctx): Promise { const { channel } = ctx.req.param(); + const targetUrl = `${baseUrl}/index/recall/index/item/${channel}.html?loadmore=1`; - const { html } = await ofetch(`${baseUrl}/index/recall/index/item/${channel}.html?loadmore=1`, { - method: 'get', + // Reason: site uses cookie-based anti-bot — first request returns 403 with set-cookie, + // second request with those cookies returns the actual JSON data. + const initResponse = await ofetch.raw(targetUrl, { headers: { + 'User-Agent': userAgent, 'Accept-Language': 'zh-CN,zh;q=0.9', }, + ignoreResponseError: true, + }); + + const cookies = (initResponse.headers.getSetCookie?.() || []).map((c) => c.split(';')[0]).join('; '); + + const { html } = await ofetch(targetUrl, { + headers: { + 'User-Agent': userAgent, + 'Accept-Language': 'zh-CN,zh;q=0.9', + Cookie: cookies, + }, }); const $ = load(html as string); @@ -46,7 +65,7 @@ async function handler(ctx): Promise { }; }); return { - title: ['国内召回公告', '国内召回新闻', '国外召回公告', '国外召回新闻'][channel - 1], + title: ['国内召回新闻', '国内召回公告', '国外召回新闻', '国外召回公告'][Number(channel) - 1], link: `${baseUrl}/index/recall/index.html`, item: items, language: 'zh-CN',