From 12b45b27e44bc8f6728fecda7816f511bb63639a Mon Sep 17 00:00:00 2001 From: Kenny Fong Date: Mon, 29 Jul 2024 20:28:02 +0800 Subject: [PATCH] =?UTF-8?q?fix(route/keylol):=20=E6=94=B9=E8=BF=9B?= =?UTF-8?q?=E6=9C=89=E9=98=85=E8=AF=BB=E6=9D=83=E9=99=90=E7=9A=84=E5=B8=96?= =?UTF-8?q?=E5=AD=90=20(#16285)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(route/keylol): 改进有阅读权限的帖子 未登录或权限不足时 pubDate author 会使用列表页的数据 description 会显示错误讯息 * change type * 设置 KEYLOL_COOKIE 登录账户 * Update doc for KEYLOL_COOKIE --- lib/config.ts | 6 ++++ lib/routes/keylol/index.ts | 56 ++++++++++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/lib/config.ts b/lib/config.ts index ce1604e4a..8ee4d3956 100644 --- a/lib/config.ts +++ b/lib/config.ts @@ -168,6 +168,9 @@ export type Config = { javdb: { session?: string; }; + keylol: { + cookie?: string; + }; lastfm: { api_key?: string; }; @@ -534,6 +537,9 @@ const calculateValue = () => { javdb: { session: envs.JAVDB_SESSION, }, + keylol: { + cookie: envs.KEYLOL_COOKIE, + }, lastfm: { api_key: envs.LASTFM_API_KEY, }, diff --git a/lib/routes/keylol/index.ts b/lib/routes/keylol/index.ts index d95979983..b149d146f 100644 --- a/lib/routes/keylol/index.ts +++ b/lib/routes/keylol/index.ts @@ -1,13 +1,17 @@ import { Route } from '@/types'; import cache from '@/utils/cache'; +import { config } from '@/config'; import got from '@/utils/got'; import { load } from 'cheerio'; import timezone from '@/utils/timezone'; -import { parseDate } from '@/utils/parse-date'; +import { parseDate, parseRelativeDate } from '@/utils/parse-date'; import parser from '@/utils/rss-parser'; import queryString from 'query-string'; const threadIdRegex = /(\d+)-\d+-\d+/; +const header = { + Cookie: config.keylol.cookie ?? undefined, +}; export const route: Route = { path: '/:path', @@ -15,6 +19,20 @@ export const route: Route = { parameters: { path: '路径,默认为热点聚焦' }, categories: ['game'], example: '/keylol/f161-1', + features: { + requireConfig: [ + { + name: 'KEYLOL_COOKIE', + optional: true, + description: `配置后可抓取具有阅读权限的帖子內容`, + }, + ], + requirePuppeteer: false, + antiCrawler: false, + supportBT: false, + supportPodcast: false, + supportScihub: false, + }, radar: [ { source: ['keylol.com/:path'], @@ -58,19 +76,25 @@ async function handler(ctx) { const rootUrl = 'https://keylol.com'; const currentUrl = queryString.stringifyUrl({ url: `${rootUrl}/forum.php`, query: queryParams }); - const { data: response } = await got(currentUrl); + const { data: response } = await got({ + method: 'get', + url: currentUrl, + headers: header, + }); const $ = load(response); - let items = $('tbody[id^="normalthread_"] a.xst') + let items = $('tbody[id^="normalthread_"]') .slice(0, limit) .toArray() .map((item) => { item = $(item); return { - title: item.text(), - link: new URL(item.prop('href').split('&extra=')[0], rootUrl).href, + title: item.find('a.xst').text(), + link: new URL(item.find(' a.xst').prop('href').split('&extra=')[0], rootUrl).href, + author: item.find('td.by-author cite').text(), + pubDate: parseRelativeDate(item.find('td.by-author em').text().replaceAll(' 发表', '')), }; }); @@ -78,11 +102,15 @@ async function handler(ctx) { items.map((item) => cache.tryGet(item.link, async () => { const threadId = threadIdRegex.test(item.link) ? item.link.match(threadIdRegex)[1] : queryString.parseUrl(item.link).query.tid; - const { data: detailResponse } = await got(item.link); + const { data: detailResponse } = await got({ + method: 'get', + url: item.link, + headers: header, + }); const content = load(detailResponse); - let descriptionList: any[] = []; + let descriptionList: string[] = []; const indexDiv = content('div#threadindex'); if (indexDiv.length > 0) { // post with page @@ -110,8 +138,10 @@ async function handler(ctx) { } item.description = descriptionList.join('
'); - const authorName = authorNameMap.find((a) => a.threadId === threadId); - item.author = authorName && authorName.length > 0 ? authorName[0].author : content('a.xw1').first().text(); + const realAuthorName = authorNameMap.find((a) => a.threadId === threadId); + if (realAuthorName) { + item.author = realAuthorName.author; + } item.category = content('#keyloL_thread_tags a') .toArray() .map((c) => content(c).text()); @@ -156,11 +186,15 @@ async function handler(ctx) { function getDescription($) { const descriptionEl = $('td.t_f'); descriptionEl.find('div.rnd_ai_pr').remove(); // remove ad image - return descriptionEl.html(); + return descriptionEl.length > 0 ? descriptionEl.html() : $('div.alert_info').html(); } async function getPage(url, pageTitle) { - const { data: detailResponse } = await got(url); + const { data: detailResponse } = await got({ + method: 'get', + url, + headers: header, + }); const $ = load(detailResponse, { xmlMode: true }); const content = $('root').text();