@cloud411716/fancy-webnovel 0.2.9 → 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloud411716/fancy-webnovel",
3
- "version": "0.2.9",
3
+ "version": "0.2.10",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
6
  "exports": {
@@ -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) {