@cloud411716/fancy-webnovel 0.2.10 → 0.2.11
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
|
@@ -312,49 +312,60 @@ async function scrapeChannel(ch, type) {
|
|
|
312
312
|
const intercepted = [];
|
|
313
313
|
const seen = new Set();
|
|
314
314
|
|
|
315
|
+
// 先注册拦截器,再导航到目标页(避免漏掉 initial 请求)
|
|
316
|
+
context.on("request", req => {
|
|
317
|
+
const url = req.url();
|
|
318
|
+
if (seen.has(url)) return;
|
|
319
|
+
if (/\.(css|woff|jpg|png|ico)/.test(url)) return;
|
|
320
|
+
if (!url.includes("fanqie")) return;
|
|
321
|
+
seen.add(url);
|
|
322
|
+
console.log(`[REQ] ${url}`);
|
|
323
|
+
});
|
|
324
|
+
|
|
315
325
|
page.on("response", async (resp) => {
|
|
316
326
|
const url = resp.url();
|
|
317
|
-
const ct = resp.headers()["content-type"] || "";
|
|
318
|
-
|
|
319
|
-
if (!ct.includes("json") && !ct.includes("text")) return;
|
|
320
|
-
// 跳过静态资源
|
|
327
|
+
const ct = (resp.headers()["content-type"] || "").toLowerCase();
|
|
328
|
+
if (seen.has(url)) return;
|
|
329
|
+
if (!ct.includes("json") && !ct.includes("text") && !url.includes("api")) return;
|
|
321
330
|
if (/\.(css|woff|jpg|png|ico)/.test(url)) return;
|
|
322
331
|
try {
|
|
323
332
|
const body = await resp.text();
|
|
324
333
|
if (!body || body.length < 50) return;
|
|
325
|
-
// 尝试解析 JSON
|
|
326
334
|
let parsed;
|
|
327
335
|
try { parsed = JSON.parse(body); } catch { return; }
|
|
328
|
-
// 找含书籍数据的响应
|
|
329
336
|
const str = JSON.stringify(parsed);
|
|
330
337
|
if (str.includes("bookId") || str.includes("book_name") || str.includes("bookName") || str.includes("authorName")) {
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
}
|
|
338
|
+
console.log(`[JSON] ${url}`);
|
|
339
|
+
console.log(` 预览: ${str.slice(0, 300)}`);
|
|
340
|
+
intercepted.push({ url, preview: str.slice(0, 400) });
|
|
335
341
|
}
|
|
336
342
|
} catch {}
|
|
337
343
|
});
|
|
338
344
|
|
|
339
|
-
//
|
|
345
|
+
// 直接导航到品类页(不用 waitUntil,避免卡住)
|
|
340
346
|
const cats = await extractCategories(page, ch, type);
|
|
341
347
|
if (!cats.length) {
|
|
342
|
-
await
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
348
|
+
await page.goto(`https://fanqienovel.com/rank/${ch}_${type}_${initCatId}`);
|
|
349
|
+
await page.waitForTimeout(3000);
|
|
350
|
+
const moreCats = await extractCategories(page, ch, type);
|
|
351
|
+
if (moreCats.length) {
|
|
352
|
+
console.log(` 发现 ${moreCats.length} 个品类`);
|
|
353
|
+
for (const c of moreCats.slice(0, 3)) {
|
|
354
|
+
console.log(` 探测品类: ${c.name} → ${c.href}`);
|
|
355
|
+
await page.goto(`https://fanqienovel.com${c.href}`);
|
|
356
|
+
await page.waitForTimeout(2000);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
} else {
|
|
360
|
+
console.log(` 发现 ${cats.length} 个品类`);
|
|
361
|
+
for (const c of cats.slice(0, 3)) {
|
|
362
|
+
console.log(` 探测品类: ${c.name} → ${c.href}`);
|
|
363
|
+
await page.goto(`https://fanqienovel.com${c.href}`);
|
|
364
|
+
await page.waitForTimeout(2000);
|
|
365
|
+
}
|
|
350
366
|
}
|
|
351
367
|
|
|
352
|
-
console.log(`\n===
|
|
353
|
-
for (const { url, preview } of intercepted) {
|
|
354
|
-
console.log(`URL: ${url}`);
|
|
355
|
-
console.log(`预览: ${preview}`);
|
|
356
|
-
console.log("---");
|
|
357
|
-
}
|
|
368
|
+
console.log(`\n=== 共拦截到 ${intercepted.length} 个含书籍数据的接口 ===`);
|
|
358
369
|
await browser.close();
|
|
359
370
|
return null;
|
|
360
371
|
}
|