@cloud411716/fancy-webnovel 0.2.17 → 0.2.19
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
|
@@ -57,15 +57,15 @@
|
|
|
57
57
|
|
|
58
58
|
`jjwxc.net/topten.php?orderstr={榜单ID}&t={频道ID}`
|
|
59
59
|
|
|
60
|
-
| 榜单 | orderstr |
|
|
61
|
-
|
|
62
|
-
| 月榜 | 5 |
|
|
63
|
-
| 总分榜 | 7 |
|
|
64
|
-
| 季度榜 |
|
|
65
|
-
| 收入金榜 | 12 |
|
|
66
|
-
| 完结金榜 |
|
|
67
|
-
| 勤奋指数榜 | 15 |
|
|
68
|
-
| 新手金榜 | 17 |
|
|
60
|
+
| 榜单 | orderstr | 页面布局 |
|
|
61
|
+
|------|----------|----------|
|
|
62
|
+
| 月榜 | 5 | 表格型(布局A) |
|
|
63
|
+
| 总分榜 | 7 | 表格型(布局A) |
|
|
64
|
+
| 季度榜 | 4 | 表格型(布局A) |
|
|
65
|
+
| 收入金榜 | 12 | 交替行型(布局B) |
|
|
66
|
+
| 完结金榜 | 16 | 交替行型(布局B) |
|
|
67
|
+
| 勤奋指数榜 | 15 | 表格型(布局A) |
|
|
68
|
+
| 新手金榜 | 17 | 交替行型(布局B) |
|
|
69
69
|
|
|
70
70
|
### 输出模板
|
|
71
71
|
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
*
|
|
5
5
|
* 使用 playwright-core 自己管理浏览器。
|
|
6
6
|
* 采集策略:
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* 布局 A(表格型):orderstr=5/7/4/15 等,表头含"序号/作者/作品",直接解析表格。
|
|
8
|
+
* 布局 B(交替行型):orderstr=12/16/17 等,按频道分段、书名/作者交替行解析。
|
|
9
|
+
* 详情补采:从书名 anchor 取 novelid,逐本进 onebook.php 补核心指标
|
|
10
|
+
* (收藏数/营养液/积分/字数/状态),满足规范对晋江的硬性要求。
|
|
10
11
|
* 晋江页面为 gb18030 编码:详情页用 fetch+arrayBuffer+TextDecoder('gb18030') 解码。
|
|
11
12
|
*
|
|
12
13
|
* 用法:
|
|
@@ -29,9 +30,9 @@ const DETAIL_BASE = "https://www.jjwxc.net/onebook.php";
|
|
|
29
30
|
const RANK_TYPES = [
|
|
30
31
|
{ id: "5", label: "月榜" },
|
|
31
32
|
{ id: "7", label: "总分榜" },
|
|
32
|
-
{ id: "
|
|
33
|
+
{ id: "4", label: "季度榜" },
|
|
33
34
|
{ id: "12", label: "收入金榜" },
|
|
34
|
-
{ id: "
|
|
35
|
+
{ id: "16", label: "完结金榜" },
|
|
35
36
|
{ id: "15", label: "勤奋指数榜" },
|
|
36
37
|
{ id: "17", label: "新手金榜" },
|
|
37
38
|
];
|
|
@@ -136,9 +137,42 @@ async function scrapeRank(rankTypeId, channelId) {
|
|
|
136
137
|
return null;
|
|
137
138
|
}
|
|
138
139
|
|
|
139
|
-
//
|
|
140
|
+
// 布局检测:先找含"序号"/"作者"/"作品"表头的表格,有则为布局A(表格),无为布局B(交替行)
|
|
140
141
|
data = await page.evaluate(() => {
|
|
141
|
-
|
|
142
|
+
// ── 布局 A:表格型(表头含"序号""作者""作品") ──
|
|
143
|
+
var tables = document.querySelectorAll('table');
|
|
144
|
+
for (var ti = 0; ti < tables.length; ti++) {
|
|
145
|
+
var ths = tables[ti].querySelectorAll('th');
|
|
146
|
+
var headerText = Array.from(ths).map(function(th) { return th.innerText.trim(); }).join('');
|
|
147
|
+
if (headerText.indexOf('序号') >= 0 && headerText.indexOf('作者') >= 0 && headerText.indexOf('作品') >= 0) {
|
|
148
|
+
var rows = tables[ti].querySelectorAll('tr');
|
|
149
|
+
var books = [];
|
|
150
|
+
for (var ri = 0; ri < rows.length; ri++) {
|
|
151
|
+
var cells = rows[ri].querySelectorAll('td');
|
|
152
|
+
if (cells.length < 3) continue;
|
|
153
|
+
var rankCell = cells[0].innerText.trim();
|
|
154
|
+
if (!/^\d+$/.test(rankCell)) continue;
|
|
155
|
+
var author = cells[1].innerText.trim();
|
|
156
|
+
var titleLink = cells[2].querySelector('a');
|
|
157
|
+
var title = titleLink ? titleLink.innerText.trim() : cells[2].innerText.trim();
|
|
158
|
+
var novelLink = cells[2].querySelector('a');
|
|
159
|
+
var novelid = '';
|
|
160
|
+
if (novelLink) {
|
|
161
|
+
var m = (novelLink.getAttribute('href') || '').match(/novelid=([0-9]+)/);
|
|
162
|
+
if (m) novelid = m[1];
|
|
163
|
+
}
|
|
164
|
+
var typeText = cells.length > 3 ? cells[3].innerText.trim() : '';
|
|
165
|
+
var progress = cells.length > 4 ? cells[4].innerText.trim() : '';
|
|
166
|
+
var words = cells.length > 5 ? cells[5].innerText.trim() : '';
|
|
167
|
+
var score = cells.length > 6 ? cells[6].innerText.trim() : '';
|
|
168
|
+
var pubtime = cells.length > 7 ? cells[7].innerText.trim() : '';
|
|
169
|
+
books.push({ rank: parseInt(rankCell), title: title, author: author, novelid: novelid, type: typeText, progress: progress, words: words, score: score, pubtime: pubtime });
|
|
170
|
+
}
|
|
171
|
+
return { layout: 'A', channels: [{ name: '全站', books: books }] };
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// ── 布局 B:交替行型(频道分段,书名/作者交替) ──
|
|
175
|
+
var result = { layout: 'B', channels: [] };
|
|
142
176
|
var text = document.body.innerText || "";
|
|
143
177
|
var lines = text.split(/\n/).map(function(l) { return l.trim(); }).filter(Boolean);
|
|
144
178
|
|
|
@@ -194,6 +228,8 @@ async function scrapeRank(rankTypeId, channelId) {
|
|
|
194
228
|
return result;
|
|
195
229
|
});
|
|
196
230
|
|
|
231
|
+
console.log(` ✓ 布局检测:${data.layout === 'A' ? '表格型' : '交替行型'}`);
|
|
232
|
+
|
|
197
233
|
if (!data?.channels?.length) {
|
|
198
234
|
console.error(`[jjwxc] 采集失败:未解析到榜单(页面结构可能变动或未加载)。请人工打开 ${url} 确认。`);
|
|
199
235
|
return null;
|
|
@@ -262,16 +298,27 @@ async function scrapeRank(rankTypeId, channelId) {
|
|
|
262
298
|
];
|
|
263
299
|
|
|
264
300
|
for (const ch of data.channels) {
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
301
|
+
lines.push(`## ${ch.name}`, "");
|
|
302
|
+
for (let i = 0; i < ch.books.length; i++) {
|
|
303
|
+
const b = ch.books[i];
|
|
304
|
+
lines.push(`书名:${b.title || ""}`);
|
|
305
|
+
lines.push(`作者:${b.author || ""}`);
|
|
306
|
+
if (data.layout === 'A') {
|
|
307
|
+
// 布局A(表格型):已有丰富字段,直接使用
|
|
308
|
+
if (b.type) lines.push(`类型:${b.type}`);
|
|
309
|
+
if (b.progress) lines.push(`进度:${b.progress}`);
|
|
310
|
+
if (b.words) lines.push(`字数:${b.words}`);
|
|
311
|
+
if (b.score) lines.push(`积分:${b.score}`);
|
|
312
|
+
if (b.pubtime) lines.push(`发表时间:${b.pubtime}`);
|
|
313
|
+
lines.push(`题材:${b.type ? b.type.split('-')[1] || b.type : ""}`);
|
|
314
|
+
} else {
|
|
315
|
+
// 布局B(交替行型):只有书名/作者,其他留空让详情补采
|
|
269
316
|
lines.push(`题材:${ch.name}`);
|
|
270
|
-
lines.push(`作者:${b.author || ""}`);
|
|
271
|
-
if (b.novelid) lines.push(`作品页:https://www.jjwxc.net/onebook.php?novelid=${b.novelid}`);
|
|
272
|
-
lines.push("");
|
|
273
317
|
}
|
|
274
|
-
lines.push(
|
|
318
|
+
if (b.novelid) lines.push(`作品页:https://www.jjwxc.net/onebook.php?novelid=${b.novelid}`);
|
|
319
|
+
lines.push("");
|
|
320
|
+
}
|
|
321
|
+
lines.push("--", "");
|
|
275
322
|
}
|
|
276
323
|
|
|
277
324
|
return {
|