Jelajahi Sumber

结束原因三选一:时间到/取材用尽时明确告诉用户"为什么没到上限、该怎么办"

用户问"设 100 个,时间上限是 30 分钟还是 30 分钟+100 个的时间",
暴露出一个体验问题:他设了 100 却只收到 83 个,日志里除了"时长上限"什么都没说,
只能自己猜是过滤太严还是程序漏了。

实际关系是**谁先到听谁、不相加**:
  抓够 100 个 → 停;到 30 分钟 → 也停(不管够不够数)。
上限不是保证,只是"够了就别再抓"。

原来只有"已提取满 N 个"一条 warning,另外两种结束原因一声不响。
现在三种都写成人话:

1. 已提取满 N 个,按设置停止
2. 时间到,只收了 X/Y 个。按本轮速度,收满 Y 个约需 Z 分钟
   —— 建议把「单次最长运行」调到 Z+5 分钟以上
3. 取材范围已取尽,共收 X/Y 个 —— 想收更多请增加取材
   (换关键词、加账号,或打开「再取粉丝列表」)

估算方法:本轮 T 秒收到 E 个 → 收满 L 个需要 L×T/E 秒。

一个例外:extracted = 0 时**不建议调大时间** —— 那是过滤太严或取材取不到人,
给"调时间"的建议是害人,要说清该查哪里。

真机验证(抓取预算 90 秒 / limit=100)
  收了 13 个 → "按本轮速度,收满 100 个约需 16 分钟 —— 建议调到 21 分钟以上"
  resolved=13,解析照常完成(上一轮修的独立预算生效)

顺带记录一个偶发:测试中出现过一次「用户主页上找不到 fans 入口」,
TikTok 版本未变、重跑即正常,判断为 openBySearch 返回后页面仍在渲染。
暂不加重试(加了会掩盖真问题),若频繁出现再处理。
梦境 1 Minggu lalu
induk
melakukan
02ea4c4c88
2 mengubah file dengan 77 tambahan dan 1 penghapusan
  1. 39 1
      tiktok-auto/dist/tiktok-auto.js
  2. 38 0
      tiktok-auto/src/idflow.js

+ 39 - 1
tiktok-auto/dist/tiktok-auto.js

@@ -1,5 +1,5 @@
 /*! tiktok-auto v1.0.0
- *  built 2026-10-20T11:29:19.585Z
+ *  built 2026-10-21T14:19:52.518Z
  *  modules: logger, bridge, config, wait, layout, ui, popups, tiktok, player, comment, flow, parse, uidset, filters, profile, idsource, resolve, idflow, main
  *  由 tools/build.js 自动生成 —— 请不要直接编辑本文件,改 src/ 后重新构建。
  */
@@ -6442,6 +6442,44 @@ TikTokAuto.idflow = (function () {
             }
             if (limitReached()) {
                 summary.warnings.push('已提取满 ' + settings.limit + ' 个,按设置停止');
+            } else if (settings.limit > 0 && timeUp()) {
+                /* ★ 时间先到、上限没满 —— 这是最容易被误解的一种结束:
+                 * 用户设了"提取满 100 个",看到只收了 83 个,会以为是过滤太严或程序漏了,
+                 * 而真正的原因是**两个上限谁先到听谁**:30 分钟到了就停,不管够不够数。
+                 *
+                 * 这里直接给出换算结论,省得用户自己猜:
+                 * 按本轮速度,收满 limit 个大约需要多久。
+                 *
+                 * 估算方法(简单但够用):本轮 T 秒收到 E 个 → 平均每个 E/T 个,
+                 * 那么收满 L 个需要 L × T / E 秒。实测 1800 秒 / 83 个 → 100 个约 36 分钟。
+                 */
+                var elapsedMs = Date.now() - began;
+                if (summary.extracted > 0) {
+                    var needMin = Math.ceil(
+                        settings.limit * elapsedMs / summary.extracted / 60000
+                    );
+                    summary.warnings.push(
+                        '时间到,只收了 ' + summary.extracted + '/' + settings.limit + ' 个。' +
+                        '按本轮速度,收满 ' + settings.limit + ' 个约需 ' + needMin +
+                        ' 分钟 —— 建议把「单次最长运行」调到 ' + (needMin + 5) + ' 分钟以上'
+                    );
+                    log.warn('idflow', '时间到,只收 ' + summary.extracted + ' 个;' +
+                        '按本轮速度收满 ' + settings.limit + ' 个约需 ' + needMin + ' 分钟');
+                } else {
+                    /* 一个都没收到就超时:多半不是时间不够,而是过滤太严或取材取不到人。
+                     * 这时给"调大时间"的建议是害人 —— 要说清该查哪里。 */
+                    summary.warnings.push(
+                        '时间到,一个都没收到 —— 不是时间太短,请检查取材是否取到人、' +
+                        '过滤条件是否过严(见日志里的跳过原因)'
+                    );
+                }
+            } else if (settings.limit > 0 && summary.extracted < settings.limit) {
+                /* 第三种"没到上限":取材本身跑完了(列表到底/文件读完),不是时间问题。
+                 * 这时调时间没用,得加取材量。 */
+                summary.warnings.push(
+                    '取材范围已取尽,共收 ' + summary.extracted + '/' + settings.limit +
+                    ' 个 —— 想收更多请增加取材(换关键词、加账号,或打开「再取粉丝列表」)'
+                );
             }
             log.step('idflow', '=== 提取结束:新增 ' + summary.extracted +
                 ' 个,跳过 ' + summary.skipped + ' 个,重复 ' + summary.duplicates +

+ 38 - 0
tiktok-auto/src/idflow.js

@@ -482,6 +482,44 @@ TikTokAuto.idflow = (function () {
             }
             if (limitReached()) {
                 summary.warnings.push('已提取满 ' + settings.limit + ' 个,按设置停止');
+            } else if (settings.limit > 0 && timeUp()) {
+                /* ★ 时间先到、上限没满 —— 这是最容易被误解的一种结束:
+                 * 用户设了"提取满 100 个",看到只收了 83 个,会以为是过滤太严或程序漏了,
+                 * 而真正的原因是**两个上限谁先到听谁**:30 分钟到了就停,不管够不够数。
+                 *
+                 * 这里直接给出换算结论,省得用户自己猜:
+                 * 按本轮速度,收满 limit 个大约需要多久。
+                 *
+                 * 估算方法(简单但够用):本轮 T 秒收到 E 个 → 平均每个 E/T 个,
+                 * 那么收满 L 个需要 L × T / E 秒。实测 1800 秒 / 83 个 → 100 个约 36 分钟。
+                 */
+                var elapsedMs = Date.now() - began;
+                if (summary.extracted > 0) {
+                    var needMin = Math.ceil(
+                        settings.limit * elapsedMs / summary.extracted / 60000
+                    );
+                    summary.warnings.push(
+                        '时间到,只收了 ' + summary.extracted + '/' + settings.limit + ' 个。' +
+                        '按本轮速度,收满 ' + settings.limit + ' 个约需 ' + needMin +
+                        ' 分钟 —— 建议把「单次最长运行」调到 ' + (needMin + 5) + ' 分钟以上'
+                    );
+                    log.warn('idflow', '时间到,只收 ' + summary.extracted + ' 个;' +
+                        '按本轮速度收满 ' + settings.limit + ' 个约需 ' + needMin + ' 分钟');
+                } else {
+                    /* 一个都没收到就超时:多半不是时间不够,而是过滤太严或取材取不到人。
+                     * 这时给"调大时间"的建议是害人 —— 要说清该查哪里。 */
+                    summary.warnings.push(
+                        '时间到,一个都没收到 —— 不是时间太短,请检查取材是否取到人、' +
+                        '过滤条件是否过严(见日志里的跳过原因)'
+                    );
+                }
+            } else if (settings.limit > 0 && summary.extracted < settings.limit) {
+                /* 第三种"没到上限":取材本身跑完了(列表到底/文件读完),不是时间问题。
+                 * 这时调时间没用,得加取材量。 */
+                summary.warnings.push(
+                    '取材范围已取尽,共收 ' + summary.extracted + '/' + settings.limit +
+                    ' 个 —— 想收更多请增加取材(换关键词、加账号,或打开「再取粉丝列表」)'
+                );
             }
             log.step('idflow', '=== 提取结束:新增 ' + summary.extracted +
                 ' 个,跳过 ' + summary.skipped + ' 个,重复 ' + summary.duplicates +