tt-help-cli-ycl 1.4.29 → 1.4.30
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/src/lib/search-collector.js +22 -24
package/package.json
CHANGED
|
@@ -58,6 +58,18 @@ async function scrollPage(page) {
|
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
async function waitForSearchResults(page, timeoutMs = 20000) {
|
|
62
|
+
try {
|
|
63
|
+
await page.waitForSelector(
|
|
64
|
+
'[class*="DivItemContainer"]',
|
|
65
|
+
{ timeout: timeoutMs },
|
|
66
|
+
);
|
|
67
|
+
return true;
|
|
68
|
+
} catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
61
73
|
async function processOneTab(page, tabName, keyword, allIds, excludeSet, log) {
|
|
62
74
|
const urlFn = TAB_URLS[tabName];
|
|
63
75
|
if (!urlFn) {
|
|
@@ -68,7 +80,7 @@ async function processOneTab(page, tabName, keyword, allIds, excludeSet, log) {
|
|
|
68
80
|
const tag = `[${tabName}]`;
|
|
69
81
|
const url = urlFn(keyword);
|
|
70
82
|
|
|
71
|
-
//
|
|
83
|
+
// 首屏加载
|
|
72
84
|
log(`${tag} 加载...`);
|
|
73
85
|
try {
|
|
74
86
|
await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30000 });
|
|
@@ -76,7 +88,12 @@ async function processOneTab(page, tabName, keyword, allIds, excludeSet, log) {
|
|
|
76
88
|
log(`${tag} 导航失败: ${e.message}`);
|
|
77
89
|
return;
|
|
78
90
|
}
|
|
79
|
-
|
|
91
|
+
|
|
92
|
+
// 等待搜索结果实际加载(最长 20 秒)
|
|
93
|
+
const ready = await waitForSearchResults(page, 20000);
|
|
94
|
+
if (!ready) {
|
|
95
|
+
log(`${tag} 等待超时,继续采集`);
|
|
96
|
+
}
|
|
80
97
|
|
|
81
98
|
// 首屏渲染完成后屏蔽图片/字体/媒体,加速后续滚动
|
|
82
99
|
await page.route("**/*", (route) => {
|
|
@@ -151,35 +168,16 @@ export async function collectSearchAuthors(browser, keyword, opts = {}) {
|
|
|
151
168
|
log(`[collect] 排除: [${[...excludeSet].join(", ")}]`);
|
|
152
169
|
|
|
153
170
|
const context = browser.contexts()[0];
|
|
154
|
-
const
|
|
171
|
+
const page = context.pages()[0];
|
|
155
172
|
const allIds = new Set();
|
|
156
173
|
|
|
157
|
-
//
|
|
158
|
-
const
|
|
159
|
-
const tasks = tabs.map(async (tabName, i) => {
|
|
160
|
-
let page = null;
|
|
174
|
+
// 串行:复用同一个页面,逐个 tab 采集
|
|
175
|
+
for (const tabName of tabs) {
|
|
161
176
|
try {
|
|
162
|
-
page = i === 0 ? existingPage : await context.newPage();
|
|
163
|
-
if (i > 0) newPages.push(page);
|
|
164
177
|
await processOneTab(page, tabName, keyword, allIds, excludeSet, log);
|
|
165
178
|
} catch (e) {
|
|
166
179
|
log(`[${tabName}] 异常: ${e.message}`);
|
|
167
|
-
} finally {
|
|
168
|
-
if (i > 0 && page) {
|
|
169
|
-
try {
|
|
170
|
-
await page.close();
|
|
171
|
-
} catch {}
|
|
172
|
-
}
|
|
173
180
|
}
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
await Promise.all(tasks);
|
|
177
|
-
|
|
178
|
-
// 兜底:确保所有新建页面都已关闭
|
|
179
|
-
for (const p of newPages) {
|
|
180
|
-
try {
|
|
181
|
-
if (!p.isClosed()) await p.close();
|
|
182
|
-
} catch {}
|
|
183
181
|
}
|
|
184
182
|
|
|
185
183
|
return [...allIds].sort();
|