tt-help-cli-ycl 1.4.41 → 1.4.43

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": "tt-help-cli-ycl",
3
- "version": "1.4.41",
3
+ "version": "1.4.43",
4
4
  "description": "TikTok user & video data scraper - extract ttSeller, verified, locationCreated from HTML source",
5
5
  "type": "module",
6
6
  "bin": {
package/src/cli/tag.js CHANGED
@@ -1548,7 +1548,7 @@ export async function handleTag(parsed) {
1548
1548
 
1549
1549
  export async function handleTagRefresh(parsed) {
1550
1550
  const { tagRefresh } = parsed;
1551
- const { serverUrl, port, proxy: cliProxy } = tagRefresh || {};
1551
+ const { serverUrl, port, proxy: cliProxy, webserver } = tagRefresh || {};
1552
1552
 
1553
1553
  const baseUrl = serverUrl || DEFAULT_SERVER;
1554
1554
  const defaultRefreshPort =
@@ -1743,19 +1743,23 @@ export async function handleTagRefresh(parsed) {
1743
1743
  const clientId = randomUUID();
1744
1744
  const clientMeta = { type: "tag-refresh", port: cdpPort };
1745
1745
 
1746
- // 复用 TikTokScraper
1747
- const enrichScraper = new TikTokScraper({
1748
- poolSize: 3,
1749
- proxyServer: effectiveProxy || undefined,
1750
- });
1751
- await enrichScraper.init();
1752
- log("✅ TikTokScraper 已就绪 (enrich 复用)");
1746
+ // 复用 TikTokScraper(webserver 模式下不需要本地 scraper)
1747
+ const enrichScraper = webserver
1748
+ ? null
1749
+ : new TikTokScraper({
1750
+ poolSize: 3,
1751
+ proxyServer: effectiveProxy || undefined,
1752
+ });
1753
+ if (enrichScraper) {
1754
+ await enrichScraper.init();
1755
+ log("✅ TikTokScraper 已就绪 (enrich 复用)");
1756
+ }
1753
1757
  log(` 客户端 ID: ${clientId.substring(0, 8)}...`);
1754
1758
  log("");
1755
1759
 
1756
1760
  const cleanup = () => {
1757
1761
  log("\n正在清理资源...");
1758
- enrichScraper.close().catch(() => {});
1762
+ if (enrichScraper) enrichScraper.close().catch(() => {});
1759
1763
  killEdgeProcesses(null, cdpPort);
1760
1764
  process.exit(0);
1761
1765
  };
@@ -1875,32 +1879,52 @@ export async function handleTagRefresh(parsed) {
1875
1879
  continue;
1876
1880
  }
1877
1881
 
1878
- // enrich: 先查服务端缓存,只对未知视频发 HTTP 请求
1879
- const enriched = await enrichWithServerCache(
1880
- videos,
1881
- baseUrl,
1882
- enrichScraper,
1883
- {
1884
- clientId,
1885
- clientMeta,
1886
- effectiveProxy,
1887
- log,
1888
- },
1889
- );
1890
- videos = enriched.videos;
1891
-
1892
- // CDN 限流检测
1893
- const cdnBlocked = enriched.cdnBlockedCount || 0;
1894
- if (cdnBlocked > 0) {
1895
- const cdnRatio = cdnBlocked / (videos.length || 1);
1896
- const coolSec = cdnRatio > 0.3 ? 120 : 60;
1882
+ // enrich: webserver API 或本地 HTTP view-source
1883
+ if (webserver) {
1897
1884
  log(
1898
- ` ⚠️ CDN 限流: ${cdnBlocked}/${videos.length} (${(cdnRatio * 100).toFixed(0)}%),冷却 ${coolSec} 秒后重启 scraper`,
1885
+ ` ⏳ 补充国家信息 (${videos.length} 个视频, via webserver ${webserver})...`,
1899
1886
  );
1900
- await new Promise((r) => setTimeout(r, coolSec * 1000));
1901
- log(` 正在重启 TikTokScraper...`);
1902
- await enrichScraper.restart();
1903
- log(` ✅ TikTokScraper 已重启`);
1887
+ await enrichViaWebserver(
1888
+ videos,
1889
+ webserver,
1890
+ ({ done, total, current, locationCreated }) => {
1891
+ if (done % 10 === 0 || done === total) {
1892
+ const name = current.split("/").pop().slice(0, 20);
1893
+ process.stderr.write(
1894
+ `\r [${done}/${total}] ${name} → ${locationCreated || "-"}\x1b[K`,
1895
+ );
1896
+ }
1897
+ },
1898
+ );
1899
+ process.stderr.write("\n");
1900
+ } else {
1901
+ // enrich: 先查服务端缓存,只对未知视频发 HTTP 请求
1902
+ const enriched = await enrichWithServerCache(
1903
+ videos,
1904
+ baseUrl,
1905
+ enrichScraper,
1906
+ {
1907
+ clientId,
1908
+ clientMeta,
1909
+ effectiveProxy,
1910
+ log,
1911
+ },
1912
+ );
1913
+ videos = enriched.videos;
1914
+
1915
+ // CDN 限流检测
1916
+ const cdnBlocked = enriched.cdnBlockedCount || 0;
1917
+ if (cdnBlocked > 0) {
1918
+ const cdnRatio = cdnBlocked / (videos.length || 1);
1919
+ const coolSec = cdnRatio > 0.3 ? 120 : 60;
1920
+ log(
1921
+ ` ⚠️ CDN 限流: ${cdnBlocked}/${videos.length} (${(cdnRatio * 100).toFixed(0)}%),冷却 ${coolSec} 秒后重启 scraper`,
1922
+ );
1923
+ await new Promise((r) => setTimeout(r, coolSec * 1000));
1924
+ log(` 正在重启 TikTokScraper...`);
1925
+ await enrichScraper.restart();
1926
+ log(` ✅ TikTokScraper 已重启`);
1927
+ }
1904
1928
  }
1905
1929
 
1906
1930
  // 过滤目标国家的视频和作者
package/src/lib/args.js CHANGED
@@ -181,6 +181,7 @@ function parseExploreArgs(args) {
181
181
  let exploreUserId = null;
182
182
  let exploreMaxVideos = 16;
183
183
  let exploreProxy = null;
184
+ let exploreWebserver = null;
184
185
 
185
186
  const positional = [];
186
187
  const PRESETS = ["fast", "normal", "slow", "stealth"];
@@ -221,6 +222,8 @@ function parseExploreArgs(args) {
221
222
  exploreMaxVideos = parseInt(args[++i]) || 16;
222
223
  } else if (arg === "--proxy") {
223
224
  exploreProxy = args[++i];
225
+ } else if (arg === "--webserver") {
226
+ exploreWebserver = args[++i];
224
227
  } else {
225
228
  positional.push(arg);
226
229
  }
@@ -262,6 +265,7 @@ function parseExploreArgs(args) {
262
265
  exploreUserId,
263
266
  exploreMaxVideos,
264
267
  exploreProxy,
268
+ exploreWebserver,
265
269
  urls: [],
266
270
  outputFormat: "json",
267
271
  exploreCount: 0,
@@ -1155,6 +1159,7 @@ function parseTagArgs(args) {
1155
1159
  serverUrl,
1156
1160
  port: refreshPort,
1157
1161
  proxy: scoreProxy,
1162
+ webserver: webserverUrl,
1158
1163
  },
1159
1164
  urls: [],
1160
1165
  outputFormat: "json",