Compare commits

...
2 Commits
Author SHA1 Message Date
huyue 7e2f295324 Merge branch 'hy-dev' into dev
Deploy / Build and deploy (push) Successful in 8s
2026-05-13 16:22:12 +08:00
huyueandClaude Opus 4.7 2ae3d9b802 fix(scraper): idle-scroll 用 _seen 数判 + 默认视频上限 500MB
- twitter scraper: _scroll_loop 原来用「响应体数」判 idle,Twitter 偶尔返回空的
  分页 batch 时 bodies 增长但 items 没新增,会被误判为还在加载;反之时间线确实
  到底但 batch 还在追加旧数据也会误判。改用 _seen(已处理推文 id 集合)的增量:
  没有任何新 tweet id 出现就计 idle 一次,连续 N 次到底停。比 _items 鲁棒
  (即使新 tweet 全被原创过滤掉,只要时间线还在出新内容就不停)
- jobs.py: MAX_VIDEO_MB 默认从 0(不限) 改 500MB,避免误下载几个 G 的长视频

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 16:22:08 +08:00
2 changed files with 7 additions and 6 deletions
+6 -5
View File
@@ -377,8 +377,9 @@ class XTwitterScraper:
if time.time() > deadline:
self.log("达到总时长上限,停止滚动")
break
# 先用已收集的响应数粗判,够了就停
before_bodies = len(self._bodies)
# 用「已处理推文数」判 idle(_seen 比 _items 鲁棒:即使所有新推文都被过滤掉
# 我们也知道时间线还在出新内容,不会误判到底)
before_seen = len(self._seen)
try:
await page.evaluate("window.scrollBy(0, document.body.scrollHeight)")
except Exception: # noqa: BLE001
@@ -392,15 +393,15 @@ class XTwitterScraper:
if self.since and self._oldest_seen and self._oldest_seen < self.since:
self.log(f"已滚动到 {_date_only(self._oldest_seen)},早于 since={_date_only(self.since)},停止滚动")
break
if len(self._bodies) == before_bodies:
if len(self._seen) == before_seen:
idle += 1
if idle >= self.idle_scrolls:
self.log(f"连续 {idle} 次滚动无新数据,判定到底,停止")
self.log(f"连续 {idle} 次滚动无新数据,判定到底,停止(原创 {len(self._items)} / 已处理 {len(self._seen)})")
break
else:
idle = 0
if n % 10 == 0:
self.log(f"滚动 {n} 次,已收集原创推文 {len(self._items)} 条")
self.log(f"滚动 {n} 次,原创 {len(self._items)} / 已处理 {len(self._seen)}")
def _reparse_so_far(self) -> None:
"""用目前所有响应体重新解析一遍(幂等,_seen/_items 去重)。"""
+1 -1
View File
@@ -37,7 +37,7 @@ _RUN_LOCK = asyncio.Lock()
TMP_ROOT = Path(os.environ.get("TMP_DIR", "/tmp")) / "content-harvester"
CONCURRENT_FRAGMENTS = int(os.environ.get("CONCURRENT_FRAGMENTS", "8"))
MAX_VIDEO_MB = int(os.environ.get("MAX_VIDEO_MB", "0")) # 0 = 不限
MAX_VIDEO_MB = int(os.environ.get("MAX_VIDEO_MB", "500")) # 单个视频上限,0=不限;默认 500MB 避免误下载几个 G 的长视频
@dataclass