@cloud411716/fancy-webnovel 0.1.77 → 0.1.78
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/plugins/fancy-scan/scripts/run-scan.js +22 -44
- package/plugins/fancy-scan/scripts/scraper-registry.md +3 -5
- package/plugins/fancy-scan/scripts/scrapers/cdp-utils.cjs +7 -5
- package/plugins/fancy-scan/scripts/scrapers/fanqie-rank-scraper.cjs +282 -253
- package/plugins/fancy-scan/scripts/scrapers/jjwxc-rank-scraper.cjs +193 -253
- package/plugins/fancy-scan/scripts/scrapers/node_modules/.package-lock.json +20 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/LICENSE +202 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/NOTICE +5 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/README.md +3 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/ThirdPartyNotices.txt +13 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/install_media_pack.ps1 +5 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/install_webkit_wsl.ps1 +33 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_chrome_beta_linux.sh +42 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_chrome_beta_mac.sh +13 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_chrome_beta_win.ps1 +24 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_chrome_stable_linux.sh +42 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_chrome_stable_mac.sh +12 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_chrome_stable_win.ps1 +24 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_msedge_beta_linux.sh +48 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_msedge_beta_mac.sh +11 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_msedge_beta_win.ps1 +23 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_msedge_dev_linux.sh +48 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_msedge_dev_mac.sh +11 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_msedge_dev_win.ps1 +23 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_msedge_stable_linux.sh +48 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_msedge_stable_mac.sh +11 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/bin/reinstall_msedge_stable_win.ps1 +24 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/browsers.json +75 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/cli.js +21 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/index.d.ts +17 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/index.js +17 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/index.mjs +28 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/bootstrap.js +88 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/coreBundle.js +74830 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/entry/cliDaemon.js +5 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/entry/dashboardApp.js +3 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/entry/mcp.js +10 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/entry/oopBrowserDownload.js +3 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/package.js +50 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/server/chromium/appIcon.png +0 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/server/electron/loader.js +118 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/serverRegistry.js +7347 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/serverRegistry.js.LICENSE +354 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/cli-client/channelSessions.js +141 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/cli-client/cli.js +6 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/cli-client/help.json +708 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/cli-client/minimist.js +128 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/cli-client/output.js +343 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/cli-client/program.js +404 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/cli-client/registry.js +176 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/cli-client/session.js +258 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/dashboard/appIcon.png +0 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-cli/SKILL.md +420 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/element-attributes.md +23 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/playwright-tests.md +39 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/request-mocking.md +87 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/running-code.md +241 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/session-management.md +225 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/storage-state.md +275 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/test-generation.md +433 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/tracing.md +139 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-cli/references/video-recording.md +143 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/SKILL.md +143 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/gallery-spec.md +144 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/migration.md +85 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/react.md +67 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/vue.md +75 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/skills/playwright-trace/SKILL.md +171 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/utils/extension.js +101 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/tools/utils/socketConnection.js +108 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/utilsBundle.js +90764 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/utilsBundle.js.LICENSE +2179 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/dashboard/assets/codicon-DCmgc-ay.ttf +0 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/dashboard/assets/firefox-1bWoP6pv.svg +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/dashboard/assets/firefox-beta-k3eOH_eK.svg +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/dashboard/assets/firefox-nightly-Cp5nfeDT.svg +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/dashboard/assets/index-CyWAfh-p.js +11 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/dashboard/assets/index-DhC616m4.css +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/dashboard/assets/safari-na3_-uQk.svg +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/dashboard/index.html +29 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/dashboard/playwright-logo.svg +24 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/htmlReport/index.html +16 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/htmlReport/report.css +2 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/htmlReport/report.js +32 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule--QdMvsKi.css +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-CwYYHbcZ.js +32 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/recorder/assets/codicon-DCmgc-ay.ttf +0 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/recorder/assets/index-DYjdXIbE.js +129 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/recorder/assets/index-l_lX622x.css +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/recorder/index.html +29 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/recorder/playwright-logo.svg +9 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-rXmQmLUY.js +32 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-B-dXF5JN.js +181 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/assets/urlMatch-L3liM589.js +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/assets/xtermModule-BuZfJS5v.js +7 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/codeMirrorModule.-QdMvsKi.css +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/codicon.DCmgc-ay.ttf +0 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.BLFoOugd.css +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/index.B_TqY17P.css +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/index.KZ4wOW1K.js +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/index.html +44 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/manifest.webmanifest +16 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/playwright-logo.svg +9 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/snapshot.B_Jk1wbt.js +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/snapshot.html +10 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/sw.bundle.js +4 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/uiMode.C7UW1sC9.css +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/uiMode.Dzuouizj.js +5 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/uiMode.html +18 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/vite/traceViewer/xtermModule.kHJ-D0s7.css +1 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/webp_codec.LICENSE +173 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/webp_codec.wasm +0 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/lib/xdg-open +1267 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/package.json +34 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/types/protocol.d.ts +24842 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/types/structs.d.ts +52 -0
- package/plugins/fancy-scan/scripts/scrapers/node_modules/playwright-core/types/types.d.ts +26188 -0
- package/plugins/fancy-scan/scripts/scrapers/package-lock.json +27 -0
- package/plugins/fancy-scan/scripts/scrapers/package.json +9 -0
- package/plugins/fancy-scan/scripts/scrapers/qimao-rank-scraper.cjs +200 -297
- package/plugins/fancy-scan/scripts/scrapers/zhihu-rank-scraper.cjs +80 -80
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* 知乎短篇/长篇采集脚本
|
|
4
4
|
*
|
|
5
|
+
* 使用 playwright-core 自己管理浏览器。
|
|
5
6
|
* 入口:https://www.zhihu.com/fiore/h5/vip-web
|
|
6
|
-
*
|
|
7
7
|
* 短篇(4 个榜单):推荐榜 / 热搜榜 / 热度榜 / 口碑榜
|
|
8
8
|
* 长篇(1 个榜单):长篇榜
|
|
9
9
|
*
|
|
@@ -11,30 +11,27 @@
|
|
|
11
11
|
* node zhihu-rank-scraper.js --length short # 短篇 4 个榜单
|
|
12
12
|
* node zhihu-rank-scraper.js --length long # 长篇 1 个榜单
|
|
13
13
|
* node zhihu-rank-scraper.js --length short --boards rec,hot # 指定短篇子榜
|
|
14
|
+
* node zhihu-rank-scraper.js --login-wait 60 # 等待手动登录
|
|
14
15
|
*
|
|
15
|
-
*
|
|
16
|
-
* node {SKILL_DIR}/browser-cdp/scripts/setup-cdp-chrome.js 9222
|
|
17
|
-
* 知乎需要登录态才能看完整榜单,请先用 Chrome 手动登录 zhihu.com
|
|
18
|
-
*
|
|
19
|
-
* 输出:扫榜结果/知乎{长篇|短篇}{榜单名}_{YYYYMMDD}.md
|
|
16
|
+
* 注意:知乎需要登录态才能看完整榜单。
|
|
20
17
|
*/
|
|
21
18
|
|
|
22
19
|
const fs = require("fs");
|
|
23
20
|
const path = require("path");
|
|
24
|
-
const {
|
|
21
|
+
const { chromium } = require("playwright-core");
|
|
22
|
+
const { getArg, localDateStamp, runCli } = require("./cdp-utils.cjs");
|
|
25
23
|
|
|
26
|
-
const PORT = 9222;
|
|
27
24
|
const OUTDIR = getArg(process.argv, "--outdir") || "扫榜结果";
|
|
28
25
|
const ENTRY_URL = "https://www.zhihu.com/fiore/h5/vip-web";
|
|
29
|
-
|
|
30
26
|
const LENGTH = getArg(process.argv, "--length") || "short";
|
|
27
|
+
const LOGIN_WAIT = parseInt(getArg(process.argv, "--login-wait") || "0", 10);
|
|
31
28
|
|
|
32
29
|
// 短篇 4 个榜单
|
|
33
30
|
const SHORT_BOARDS = [
|
|
34
|
-
{ id: "rec",
|
|
35
|
-
{ id: "hot",
|
|
36
|
-
{ id: "trending",
|
|
37
|
-
{ id: "reputation",
|
|
31
|
+
{ id: "rec", label: "推荐榜", tabText: "推荐榜" },
|
|
32
|
+
{ id: "hot", label: "热搜榜", tabText: "热搜榜" },
|
|
33
|
+
{ id: "trending", label: "热度榜", tabText: "热度榜" },
|
|
34
|
+
{ id: "reputation",label: "口碑榜", tabText: "口碑榜" },
|
|
38
35
|
];
|
|
39
36
|
|
|
40
37
|
// 长篇 1 个榜单
|
|
@@ -44,83 +41,88 @@ const LONG_BOARDS = [
|
|
|
44
41
|
|
|
45
42
|
const BOARDS = LENGTH === "long" ? LONG_BOARDS : SHORT_BOARDS;
|
|
46
43
|
|
|
47
|
-
// 自定义子榜(可选)
|
|
48
44
|
const customBoards = getArg(process.argv, "--boards");
|
|
49
45
|
const targetBoards = customBoards
|
|
50
|
-
? BOARDS.filter(
|
|
46
|
+
? BOARDS.filter(b => customBoards.split(",").map(s => s.trim()).includes(b.id))
|
|
51
47
|
: BOARDS;
|
|
52
48
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// 工具函数
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
function sleep(ms) {
|
|
54
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// ---------------------------------------------------------------------------
|
|
58
|
+
// 采集
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
|
|
61
|
+
async function scrapeBoard(board) {
|
|
57
62
|
console.log(` [${board.label}] 正在抓取...`);
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
const browser = await chromium.launch({ headless: true, args: ["--no-sandbox", "--disable-dev-shm-usage"] });
|
|
65
|
+
const context = await browser.newContext();
|
|
66
|
+
const page = await context.newPage();
|
|
67
|
+
|
|
68
|
+
try {
|
|
69
|
+
await page.goto(ENTRY_URL, { waitUntil: "networkidle" });
|
|
70
|
+
|
|
71
|
+
if (LOGIN_WAIT > 0) {
|
|
72
|
+
console.log(` ⏳ 等待 ${LOGIN_WAIT}s 供用户登录...`);
|
|
73
|
+
await page.waitForTimeout(LOGIN_WAIT * 1000);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const host = page.url();
|
|
77
|
+
if (host.indexOf("zhihu") === -1) {
|
|
78
|
+
console.error(` ✗ 当前页面非知乎(url=${host}),可能被重定向,已跳过。`);
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
65
81
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const clickJs = `
|
|
72
|
-
(function(){
|
|
73
|
-
const target = ${JSON.stringify(board.tabText)};
|
|
74
|
-
const candidates = Array.from(document.querySelectorAll('a, button, div, span, li'))
|
|
75
|
-
.filter((el) => {
|
|
76
|
-
const t = (el.innerText || '').trim();
|
|
82
|
+
// 点击 tab
|
|
83
|
+
const clicked = await page.evaluate((target) => {
|
|
84
|
+
const candidates = Array.from(document.querySelectorAll("a, button, div, span, li"))
|
|
85
|
+
.filter(el => {
|
|
86
|
+
const t = (el.innerText || "").trim();
|
|
77
87
|
return t === target || t.startsWith(target);
|
|
78
88
|
});
|
|
79
|
-
if (candidates.length
|
|
89
|
+
if (!candidates.length) return false;
|
|
80
90
|
candidates[0].click();
|
|
81
|
-
return
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
91
|
+
return true;
|
|
92
|
+
}, board.tabText);
|
|
93
|
+
|
|
94
|
+
if (!clicked) {
|
|
95
|
+
console.error(` [${board.label}] 点击 tab 失败`);
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
89
98
|
|
|
90
|
-
|
|
91
|
-
await new Promise((r) => setTimeout(r, 2500));
|
|
99
|
+
await page.waitForTimeout(2500);
|
|
92
100
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
const storiesJs = `
|
|
96
|
-
(function(){
|
|
101
|
+
// 提取故事列表
|
|
102
|
+
const stories = await page.evaluate(() => {
|
|
97
103
|
const items = [];
|
|
98
104
|
const seen = new Set();
|
|
99
|
-
|
|
100
|
-
// 策略 1:找所有含故事标题的 anchor
|
|
101
105
|
const anchors = document.querySelectorAll('a[href*="/p/"], a[href*="/question/"], a[href*="/xen/"]');
|
|
102
106
|
anchors.forEach((a, i) => {
|
|
103
|
-
const href = a.href ||
|
|
107
|
+
const href = a.href || "";
|
|
104
108
|
if (!href || seen.has(href)) return;
|
|
105
|
-
const text = (a.innerText ||
|
|
109
|
+
const text = (a.innerText || "").trim();
|
|
106
110
|
if (!text || text.length < 4 || text.length > 200) return;
|
|
107
|
-
// 跳过导航/按钮文字
|
|
108
111
|
if (/^(首页|发现|等你来答|登录|注册|更多|查看全部)$/.test(text)) return;
|
|
109
112
|
seen.add(href);
|
|
110
|
-
items.push({rank: i + 1, title: text.split(
|
|
113
|
+
items.push({ rank: i + 1, title: text.split("\n")[0].trim(), url: href });
|
|
111
114
|
});
|
|
115
|
+
return items.slice(0, 100);
|
|
116
|
+
});
|
|
112
117
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
return [];
|
|
118
|
+
if (!stories || stories.length === 0) {
|
|
119
|
+
console.warn(` [${board.label}] 未提取到故事`);
|
|
120
|
+
return [];
|
|
121
|
+
}
|
|
122
|
+
return stories;
|
|
123
|
+
} finally {
|
|
124
|
+
await browser.close();
|
|
121
125
|
}
|
|
122
|
-
|
|
123
|
-
return stories;
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
function buildBoardMarkdown(board, stories, date) {
|
|
@@ -129,36 +131,35 @@ function buildBoardMarkdown(board, stories, date) {
|
|
|
129
131
|
"",
|
|
130
132
|
`> 数据来源:${ENTRY_URL} → ${board.label}`,
|
|
131
133
|
`> 篇幅:${LENGTH === "long" ? "长篇" : "短篇"}`,
|
|
132
|
-
|
|
134
|
+
"> 知乎需要登录态才能看完整榜单,请确认已登录",
|
|
133
135
|
"",
|
|
134
136
|
`## ${board.label}内容`,
|
|
135
137
|
"",
|
|
136
138
|
];
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
lines.push("(未提取到数据,可能页面结构变化或需要登录)", "");
|
|
139
|
+
if (!stories.length) {
|
|
140
|
+
lines.push("(未提取到数据,可能页面结构变化或需要登录)", "", "---", "");
|
|
140
141
|
} else {
|
|
141
|
-
stories.forEach(
|
|
142
|
+
stories.forEach(s => {
|
|
142
143
|
lines.push(`### ${s.rank}. ${s.title || "(无标题)"}`);
|
|
143
144
|
if (s.url) lines.push(`- 链接:${s.url}`);
|
|
144
145
|
lines.push("", "---", "");
|
|
145
146
|
});
|
|
146
147
|
}
|
|
147
|
-
|
|
148
148
|
return lines.join("\n");
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
// 入口
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
|
|
155
|
+
async function main() {
|
|
152
156
|
const date = localDateStamp();
|
|
153
157
|
fs.mkdirSync(OUTDIR, { recursive: true });
|
|
154
158
|
|
|
155
159
|
let written = 0;
|
|
156
160
|
for (const board of targetBoards) {
|
|
157
|
-
const stories = scrapeBoard(
|
|
158
|
-
if (stories === null)
|
|
159
|
-
// 采集失败(导航失败 / tab 找不到),跳过这个榜单继续下一个
|
|
160
|
-
continue;
|
|
161
|
-
}
|
|
161
|
+
const stories = await scrapeBoard(board);
|
|
162
|
+
if (stories === null) continue;
|
|
162
163
|
|
|
163
164
|
const md = buildBoardMarkdown(board, stories, date);
|
|
164
165
|
const filename = `知乎${LENGTH === "long" ? "长篇" : "短篇"}${board.label}_${date}.md`;
|
|
@@ -167,7 +168,6 @@ function main() {
|
|
|
167
168
|
console.log(` ✓ ${filename} (${stories.length} 条)`);
|
|
168
169
|
written++;
|
|
169
170
|
}
|
|
170
|
-
|
|
171
171
|
return written;
|
|
172
172
|
}
|
|
173
173
|
|