@cloud411716/fancy-webnovel 0.2.8 → 0.2.10
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
CHANGED
|
@@ -249,6 +249,7 @@ function cleanDesc(raw) {
|
|
|
249
249
|
// ---------------------------------------------------------------------------
|
|
250
250
|
|
|
251
251
|
const args = process.argv.slice(2);
|
|
252
|
+
const PROBE = getArg(args, "--probe") !== null;
|
|
252
253
|
const LOGIN_WAIT = parseInt(getArg(args, "--login-wait") || "0", 10);
|
|
253
254
|
const OUTDIR = getArg(args, "--outdir") || ".";
|
|
254
255
|
const CHANNEL = getArg(args, "--channel") || "1";
|
|
@@ -306,6 +307,58 @@ async function scrapeChannel(ch, type) {
|
|
|
306
307
|
console.log(` ⚠ 页面未挂载 __INITIAL_STATE__,将尝试兜底扫描,结果可能不完整。`);
|
|
307
308
|
}
|
|
308
309
|
|
|
310
|
+
// ─── 调试模式:拦截所有请求,找出真实数据接口 ───
|
|
311
|
+
if (PROBE) {
|
|
312
|
+
const intercepted = [];
|
|
313
|
+
const seen = new Set();
|
|
314
|
+
|
|
315
|
+
page.on("response", async (resp) => {
|
|
316
|
+
const url = resp.url();
|
|
317
|
+
const ct = resp.headers()["content-type"] || "";
|
|
318
|
+
// 只关心 JSON 响应
|
|
319
|
+
if (!ct.includes("json") && !ct.includes("text")) return;
|
|
320
|
+
// 跳过静态资源
|
|
321
|
+
if (/\.(css|woff|jpg|png|ico)/.test(url)) return;
|
|
322
|
+
try {
|
|
323
|
+
const body = await resp.text();
|
|
324
|
+
if (!body || body.length < 50) return;
|
|
325
|
+
// 尝试解析 JSON
|
|
326
|
+
let parsed;
|
|
327
|
+
try { parsed = JSON.parse(body); } catch { return; }
|
|
328
|
+
// 找含书籍数据的响应
|
|
329
|
+
const str = JSON.stringify(parsed);
|
|
330
|
+
if (str.includes("bookId") || str.includes("book_name") || str.includes("bookName") || str.includes("authorName")) {
|
|
331
|
+
if (!seen.has(url)) {
|
|
332
|
+
seen.add(url);
|
|
333
|
+
intercepted.push({ url, preview: str.slice(0, 400) });
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
} catch {}
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// 触发几个品类页的请求
|
|
340
|
+
const cats = await extractCategories(page, ch, type);
|
|
341
|
+
if (!cats.length) {
|
|
342
|
+
await scrollLoad(page, 2);
|
|
343
|
+
sleep(1000);
|
|
344
|
+
}
|
|
345
|
+
const targets = cats.length ? cats.slice(0, 3) : [{ name: "入口页", href: `/rank/${ch}_${type}_${initCatId}` }];
|
|
346
|
+
for (const c of targets) {
|
|
347
|
+
console.log(` 探测: ${c.name} → ${c.href}`);
|
|
348
|
+
await page.goto(`https://fanqienovel.com${c.href}`, { waitUntil: "networkidle" });
|
|
349
|
+
await page.waitForTimeout(2000);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
console.log(`\n=== 拦截到的接口 (${intercepted.length}) ===\n`);
|
|
353
|
+
for (const { url, preview } of intercepted) {
|
|
354
|
+
console.log(`URL: ${url}`);
|
|
355
|
+
console.log(`预览: ${preview}`);
|
|
356
|
+
console.log("---");
|
|
357
|
+
}
|
|
358
|
+
await browser.close();
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
|
|
309
362
|
// 提取品类菜单
|
|
310
363
|
let categories = await extractCategories(page, ch, type);
|
|
311
364
|
if (!categories.length) {
|
|
@@ -105,7 +105,8 @@ export const scan = {
|
|
|
105
105
|
`2. 分析爆款书籍的题材、卖点、节奏、人设等特征`,
|
|
106
106
|
`3. 生成扫榜报告(包含:市场趋势、热门题材分析、用户画像、竞争度评估)`,
|
|
107
107
|
`4. 给出 3-5 个可行的选题方向建议`,
|
|
108
|
-
`5.
|
|
108
|
+
`5. 先创建空文件(如果不存在),再追加报告内容:\n` +
|
|
109
|
+
` touch ${topicFile}\n` +
|
|
109
110
|
` echo "你的报告内容" >> ${topicFile}\n` +
|
|
110
111
|
` (使用 tee -a 或 >> ,不要覆盖现有内容)`,
|
|
111
112
|
``,
|