# 单分子 **Repository Path**: aiaiqq/monomolecule ## Basic Information - **Project Name**: 单分子 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-28 - **Last Updated**: 2026-10-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 知乎收藏家(zhihu-collector) 基于 **PySide6 + QtWebEngine** 的桌面软件:正常浏览知乎,页面注入"收藏"按钮,一键把回答/专栏文章保存到本地(SQLite 元数据 + HTML 快照),并可随时离线阅读。 ## 环境与运行(UV) ```powershell uv sync # 创建 .venv 并安装依赖 uv run main.py # 启动软件 ``` ## 打包为可执行程序 ```powershell uv run pyinstaller --noconfirm --clean --windowed --name ZhihuCollector --add-data "inject.js;." main.py ``` 产物位于 `dist/ZhihuCollector/`(整个文件夹一起分发,双击 `ZhihuCollector.exe` 运行)。打包后收藏数据保存在 `dist/ZhihuCollector/data/` 下。 ## 下载已打包的 Windows 版本 仓库 `release/` 目录下存放分卷压缩包(Gitee 单文件限 100MB,故切分): ```powershell # 1. 下载全部 3 个分卷后,在所在目录执行合并 cmd /c copy /b ZhihuCollector.zip.001+ZhihuCollector.zip.002+ZhihuCollector.zip.003 ZhihuCollector.zip # 2. 校验(可选) certutil -hashfile ZhihuCollector.zip SHA256 # 期望 SHA256: 3a60abb5860bedcb96d46edb9e7510420590675ef46ca7d764e68628c9df2b6c # 3. 解压 ZhihuCollector.zip,双击 ZhihuCollector/ZhihuCollector.exe 运行 ``` ## 功能 - 内置浏览器内核(QtWebEngine/Chromium): - 多标签浏览(`Ctrl+T` 新建、`Ctrl+W` 关闭),`target=_blank` 与第三方登录弹窗在本窗口新标签内打开。 - 地址栏智能识别:输入网址直接访问,输入关键词回车自动搜索知乎内容;工具栏"🔍 搜知乎"可强制按关键词搜索。 - 知乎登录:伪装为 Chrome 128 的 UA + 独立持久化 Profile,登录页/扫码登录/密码登录均可正常使用,Cookie 跨启动保留。 - 常用快捷键:`F5`/`Ctrl+R` 刷新、`Alt+←/→` 前进后退、`Ctrl+L` 聚焦地址栏、`Ctrl+±/0` 页面缩放。 - 页面权限(通知/摄像头等)默认拒绝以避免弹窗,仅放行全屏;下载文件保存到 `data/downloads/`。 - Web 注入:回答(列表页每条)、专栏文章(`/p/xxx`)、评论(逐条"收藏评论")都有收藏按钮;已收藏的条目自动显示"已收藏"。 - 完整内容提取(保存到本地可离线阅读): - 正文自动展开长回答/长文章的折叠,取到完整 HTML 与纯文本; - 图片清单交给后台线程下载到 `data/articles//`,快照里的远程地址改写为本地相对路径;下载失败则保留在线地址; - 知乎中间跳转链接(`link.zhihu.com/?target=…`)还原为真实外链; - 回答/文章快照会附带当前已加载的评论(作者、时间、赞同、正文)。 - 收藏类型:回答 / 专栏文章 / 评论,评论快照记录所属内容标题与链接。 - DeepSeek 自动摘要(工具栏"⚙ 设置"): - 配置 API Key / Base URL / 模型 / 自动摘要开关 / 送入模型的最大字符数,保存在 `data/settings.json`;也支持环境变量 `DEEPSEEK_API_KEY`、`DEEPSEEK_BASE_URL`、`DEEPSEEK_MODEL` 覆盖; - 每次收藏后在后台线程调用 `chat/completions` 生成中文摘要,写入数据库与快照(快照顶部"摘要"区块),收藏夹可直接看到摘要列; - 内容短于 120 字时直接用原文当摘要,不发起请求;未配置 Key / 网络异常 / 接口报错只提示,不影响收藏本身。 - 自动抽取标签(参考 xreader 的"基于内容自动分类"思路): - 摘要生成成功后按 `auto_tag` 开关再调一次 LLM,输出 3-5 个最贴切的中文标签(去重、限长),写入 `articles.tags` 与快照(标签块紧跟摘要块); - 收藏夹顶部"标签筛选"下拉按文章数量降序列出所有标签,点击即可只看该标签下的文章;关键字搜索也命中标签; - 关闭 `auto_tag` 时只生成摘要、不发起第二次 LLM 调用;标签失败仅提示,不影响收藏本身; - 老库(无 `tags` 列)通过 `Store._migrate()` 自动 `ALTER TABLE` 补列。 - 公式渲染(KaTeX): - 快照 HTML 自动注入 KaTeX(CDN)+ `auto-render`,按 delimiters 自动区分行内(`$x^2$`)与段间(`$$\int_0^1 f dx$$`);段间公式居中、与正文留出间距; - 关闭 `render_math` 后快照不再加载 KaTeX,公式文本(`$x^2$`、`$$...$$`)仍作为原文保留可读; - KaTeX 解析失败时(`throwOnError: false`)回退为原文,不破坏版面。 - 收藏夹(工具栏"★ 收藏夹"):搜索(含正文 / 摘要 / 标签)、按标签筛选、双击阅读本地快照、浏览器打开原文、删除(同时清理快照图片目录)、**导出 HTML / PDF**(支持选中或全部,可选是否打包图片目录;PDF 用项目自带的 WebEngine 离屏渲染,无需联网)。 - 数据位置:项目目录下 `data/collections.db`、`data/articles/*.html`、`data/articles//`(快照图片)、`data/browser/`(浏览器登录态与缓存)、`data/downloads/`、`data/settings.json`(API 配置)。 ## 技术要点 - 浏览器内核:自定义 `QWebEngineProfile("zhihu-collector")`,存储目录 `data/browser/`;`ForcePersistentCookies` + Chrome UA,保证知乎登录与登录态持久化。 - `QWebEngineScript`(主世界,DocumentCreation/DocumentReady)注入 `qrc:///qtwebchannel/qwebchannel.js` 与 `inject.js`。 - `QWebChannel` 注册 `bridge` 对象(每个标签页一个通道、共享同一 `bridge`),JS 调用 `saveArticle` / `getSavedIds` 与 Python 通信。 - `MutationObserver` 监听知乎 SPA 动态加载的新回答并补挂按钮。 - `main.py` 启动前设置 `QTWEBENGINE_CHROMIUM_FLAGS=--ignore-gpu-blocklist --enable-unsafe-swiftshader`:显卡/远程桌面环境下 WebGL 被拉黑会导致知乎返回空白风控页。 - 知乎页面渲染为空白(正文极短)时状态栏提示可能是安全验证,便于排查。 - 快照落盘后由 `ImageDownloader`(线程池 + urllib)抓取正文图片并改写 HTML,不阻塞界面;关闭窗口时取消未完成任务。 - 摘要由 `DeepSeekClient`(线程池 + urllib,OpenAI 兼容的 `POST {base_url}/chat/completions`)生成,通过 Qt 信号回主线程落库;快照用 `` 标记占位,`Store.set_summary` 替换为摘要区块(旧快照回退到 `` 之后插入)。 - 标签同样由 `DeepSeekClient`(第二次调用 `chat/completions`)抽取,通过 `tagged` / `tag_failed` 信号回主线程;快照用 `` 占位,`Store.set_tags` 替换为标签区块(旧快照回退到摘要块后 / `` 之后插入)。 - 公式渲染:`_PAGE_TMPL` 注入 KaTeX 0.16.9(jsDelivr CDN)的 CSS + `katex.min.js` + `auto-render.min.js`,并在 `` 末尾内联渲染脚本 `renderMathInElement(document.body, {delimiters: ['$$'\\[\\$\\(\\), $display]})`,区分行内与段间;`Store.settings_provider` 读取 `render_math` 关闭时不注入资源;失败回退到原文(`throwOnError: false`)。 - 数据库升级:`Store._migrate()` 检测并补充 `summary` 与 `tags` 列,老库可直接使用。 - 导出:`exporter.py` 提供 `Exporter.export_html(article, dest, include_images=True)` 同步复制快照 + 图片目录;`Exporter.export_pdf(article, dest, parent)` 临时起离屏 `QWebEnginePage`,异步转 PDF,通过 `finished(ok, path, err)` 信号收尾。批量导出在主线程串行 `QEventLoop` 等待每篇完成,保证 WebEngine 单页稳定。 ## 文件结构 ``` main.py 入口(浏览器内核参数 + QApplication) browser.py 主窗口:多标签浏览器、Profile/UA、搜索、下载、注入安装、摘要/标签/图片联动 bridge.py QWebChannel 桥接对象(saveArticle / getSavedIds) inject.js 页面注入脚本(回答/文章/评论收藏按钮 + 内容与图片提取) image_downloader.py 快照图片本地化(下载 + 引用重写) deepseek.py DeepSeek Chat Completions 摘要 + 标签客户端 settings.py 配置读写(data/settings.json + 环境变量覆盖,含 auto_summary / auto_tag) settings_dialog.py DeepSeek 设置对话框(自动摘要 + 自动标签开关) store.py SQLite + HTML 快照存储(摘要/标签/评论区块渲染、字段迁移、按标签过滤) collection_dialog.py 收藏夹对话框(摘要/标签列、标签筛选、导出 HTML/PDF) exporter.py 快照导出(HTML 直接复制 + 图片目录;PDF 用 QtWebEngine 渲染) PLAN.md 开发计划与待验证项 ```