From 01078ef30c02e456b93f942cb5a65edbd4c8fab2 Mon Sep 17 00:00:00 2001 From: yetingsky Date: Fri, 20 Mar 2026 21:43:02 +0800 Subject: [PATCH] feat(jisilu): add timeline and question adapters for jisilu.cn --- src/clis/jisilu/question.ts | 84 +++++++++++++++++++++++++++++++++++++ src/clis/jisilu/timeline.ts | 69 ++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 src/clis/jisilu/question.ts create mode 100644 src/clis/jisilu/timeline.ts diff --git a/src/clis/jisilu/question.ts b/src/clis/jisilu/question.ts new file mode 100644 index 00000000..720ca7bc --- /dev/null +++ b/src/clis/jisilu/question.ts @@ -0,0 +1,84 @@ +/** + * 集思录帖子详情适配器 + * 获取帖子正文和评论 + */ +import { cli, Strategy } from "../../registry.js"; +import type { IPage } from "../../types.js"; + +cli({ + site: "jisilu", + name: "question", + description: "集思录帖子详情 (正文+评论)", + domain: "www.jisilu.cn", + strategy: Strategy.PUBLIC, + browser: true, + + args: [ + { name: "id", type: "str", required: true, help: "帖子ID或URL" }, + { name: "limit", type: "int", default: 50, help: "评论数量限制" }, + ], + + columns: ["type", "author", "content", "time", "likes"], + + func: async (page: IPage, kwargs) => { + let questionId = kwargs.id; + const idMatch = kwargs.id.match(/question\/(\d+)/); + if (idMatch) questionId = idMatch[1]; + + const url = `https://www.jisilu.cn/question/${questionId}`; + await page.goto(url); + await page.wait(2); + + const data = await page.evaluate(` + (function() { + var results = []; + var title = document.querySelector('h1'); + var titleText = title ? title.textContent.trim() : ''; + var postContent = document.querySelector('.aw-question-detail-txt'); + var postText = postContent ? postContent.textContent.trim() : ''; + var postTimeEl = document.querySelector('.aw-question-detail-meta'); + var postTimeText = postTimeEl ? postTimeEl.textContent : ''; + var postTimeMatch = postTimeText.match(/发表时间\\s*(\\d{4}-\\d{2}-\\d{2}\\s+\\d{2}:\\d{2})/); + var postTime = postTimeMatch ? postTimeMatch[1] : ''; + + results.push({ + type: 'post', + author: '', + content: postText.substring(0, 500), + time: postTime, + likes: 0 + }); + + var answers = document.querySelectorAll('.aw-item[id^="answer_list_"]'); + var limit = ${kwargs.limit}; + + for (var i = 0; i < answers.length && i < limit; i++) { + var answer = answers[i]; + var authorEl = answer.querySelector('.aw-user-name'); + var contentEl = answer.querySelector('.markitup-box'); + var timeEl = answer.querySelector('.aw-dynamic-topic-meta span'); + + if (authorEl && contentEl) { + var author = authorEl.textContent.trim(); + var content = contentEl.textContent.trim().substring(0, 300); + var timeText = timeEl ? timeEl.textContent : ''; + var timeMatch = timeText.match(/(\\d{4}-\\d{2}-\\d{2}\\s+\\d{2}:\\d{2})/); + var time = timeMatch ? timeMatch[1] : ''; + + results.push({ + type: 'reply', + author: author, + content: content, + time: time, + likes: 0 + }); + } + } + + return results; + })() + `); + + return data; + }, +}); diff --git a/src/clis/jisilu/timeline.ts b/src/clis/jisilu/timeline.ts new file mode 100644 index 00000000..813912db --- /dev/null +++ b/src/clis/jisilu/timeline.ts @@ -0,0 +1,69 @@ +/** + * 集思录个人 Timeline 适配器 + * 需要登录状态,访问 /home/mine/#all 页面 + */ +import { cli, Strategy } from "../../registry.js"; +import type { IPage } from "../../types.js"; + +cli({ + site: "jisilu", + name: "timeline", + description: "集思录个人时间线 (需登录)", + domain: "www.jisilu.cn", + strategy: Strategy.COOKIE, + browser: true, + + args: [{ name: "limit", type: "int", default: 20, help: "返回条目数量" }], + + columns: ["id", "type", "title", "author", "content", "url"], + + func: async (page: IPage, kwargs) => { + const limit = kwargs.limit || 20; + + await page.goto("https://www.jisilu.cn/home/mine/#all"); + await page.wait(3); + + const data = await page.evaluate(` + (function() { + var results = []; + var items = document.querySelectorAll('.aw-item'); + + for (var i = 0; i < items.length; i++) { + var item = items[i]; + var linkEl = item.querySelector('a[href*="/question/"]'); + var titleEl = item.querySelector('h4 a, .title a'); + var authorEl = item.querySelector('.aw-user-name'); + var contentEl = item.querySelector('.markitup-box, .aw-question-content, .content'); + + if (linkEl || titleEl) { + var url = (linkEl && linkEl.href) || (titleEl && titleEl.href) || ''; + var idMatch = url.match(/question\\/(\\d+)/); + var title = (titleEl && titleEl.textContent.trim()) || (linkEl && linkEl.textContent.trim()) || ''; + var content = ''; + if (contentEl) { + content = contentEl.textContent.trim(); + } + + var type = 'post'; + if (item.querySelector('.aw-answer-list') || item.textContent.indexOf('回复了') > -1) { + type = 'reply'; + } + + results.push({ + id: idMatch ? idMatch[1] : '', + type: type, + title: title.substring(0, 100), + author: (authorEl && authorEl.textContent.trim()) || '', + content: content.substring(0, 200), + url: url + }); + } + } + + return results; + })() + `); + + return (data || []).slice(0, limit); + }, +});