diff --git a/README.md b/README.md index eded9f1..5629d53 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ - 🔗 **自动检测** — 聊天中出现 `linux.do` 链接立即触发 - 🛡️ **绕过 Cloudflare** — 使用 [Scrapling](https://github.com/D4Vinci/Scrapling) 的 StealthySession 自动解 Turnstile -- 📸 **截图预览** — 全页面截图(1280×1024) +- 📸 **智能截图** — 视口截图显示主帖,自动隐藏导航栏/侧边栏,可选全页模式 - 📝 **内容摘要** — 提取标题 + 正文前 400 字 - ⚡ **异步非阻塞** — Scrapling 在独立线程池运行,不阻塞 AstrBot 主循环 - 💾 **缓存机制** — 30 分钟内相同链接直接返回缓存截图 @@ -98,6 +98,7 @@ https://linux.do/t/topic/1378383 | `cache_ttl` | 缓存有效期(秒),设为 0 关闭缓存 | 1800 | | `max_content_length` | 内容摘要最大长度(字符) | 400 | | `screenshot_timeout` | 截图超时(秒) | 15 | +| `screenshot_full_page` | 全页截图模式(false=仅视口,更实用) | false | ## ⚠️ 注意事项 diff --git a/_conf_schema.json b/_conf_schema.json index 132f547..ab4f9ec 100644 --- a/_conf_schema.json +++ b/_conf_schema.json @@ -16,5 +16,11 @@ "type": "int", "default": 15, "hint": "Max seconds to wait for page screenshot." + }, + "screenshot_full_page": { + "description": "Full page screenshot mode", + "type": "bool", + "default": false, + "hint": "When false (default), captures viewport only — shows the first post cleanly. Set to true for full thread capture (larger file size)." } } diff --git a/main.py b/main.py index 7b0064d..a36c796 100644 --- a/main.py +++ b/main.py @@ -169,17 +169,43 @@ class LinuxDoPreviewPlugin(Star): return None page = ctx.new_page() - page.set_viewport_size({"width": 1280, "height": 1024}) + page.set_viewport_size({"width": 1280, "height": 900}) - # 导航(已有 cf_clearance cookie,不应再触发 Cloudflare) - page.goto(url, wait_until="load", timeout=timeout_ms) - page.wait_for_timeout(3000) + # ── 导航:等 networkidle 确保 JS 动态内容加载完成 ── + page.goto(url, wait_until="networkidle", timeout=timeout_ms) + # ── 等待 Discourse 帖子内容渲染 ── + try: + page.wait_for_selector(".cooked", timeout=min(timeout_ms, 10000)) + except Exception: + page.wait_for_timeout(3000) # 回退:固定等待 + + # ── 隐藏固定元素,避免截图杂乱/重复 ── + page.evaluate("""() => { + const hide = (sel) => { + const el = document.querySelector(sel); + if (el) el.style.display = 'none'; + }; + hide('.d-header'); // 顶部导航栏 + hide('.sidebar-wrapper'); // 左侧边栏 + hide('.topic-navigation-wrapper'); // 帖子导航条 + hide('.footer-nav.visible'); // 底部导航 + + // 滚动到第一篇帖子正文 + const firstPost = document.querySelector('.cooked'); + if (firstPost) firstPost.scrollIntoView({block: 'start'}); + }""") + + page.wait_for_timeout(1000) # 等待滚动稳定 + 懒加载图片 + + # ── 截图:默认视口模式,更实用的预览尺寸 ── + full_page = self.config.get("screenshot_full_page", False) page.screenshot( path=str(save_path), - full_page=True, + full_page=full_page, timeout=timeout_ms, ) + sz = save_path.stat().st_size logger.info( f"[LinuxDoPreview] 截图保存: {save_path.name} ({sz / 1024:.1f} KB)"