# 1346488 **Repository Path**: mili23356/1346488 ## Basic Information - **Project Name**: 1346488 - **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-30 - **Last Updated**: 2026-10-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 知乎收藏器 · ZhihuSaver 基于 **Python + PySide6 + Qt WebEngine** 的桌面端知乎浏览与收藏工具。 内置 Chromium 内核浏览器,在知乎页面**自动注入**一个悬浮「★ 收藏」按钮, 一键把回答 / 文章 / 想法 / 问题正文(含图片)保存到本机 SQLite,支持离线阅读与导出。 --- ## 功能 ### 浏览 - 内嵌 Qt WebEngine(Chromium)浏览器,多标签、前进/后退/刷新、地址栏搜索 - **登录态持久化**:Cookie、localStorage、缓存都落在 `data/webengine/`,重启无需重新登录 - `window.open` 弹窗自动开新标签页 ### 自动注入的收藏能力 - 打开知乎任意页面后,右下角**自动出现**蓝色「★」悬浮按钮(Shadow DOM 渲染,样式与知乎完全隔离,不受其 CSS / CSP 影响) - 点击按钮弹出收藏面板,可以选择保存**整页正文**或**当前选中的内容** - **按 URL 里的 answer / article id 精确定位当前卡片**:问题页会同时渲染多张回答卡片,不会抓错别人那条 - 解析卡片的 `data-zop` 与 `meta[itemprop]`,自动带出**作者、赞同数、评论数、发布时间**, 并显示在面板徽标、收藏夹列表和阅读页里 - 折叠的长回答会先自动展开再抽取 - 自动清理广告、推荐位、操作栏、送礼区块、按钮、图标、loading 骨架 - 自动把懒加载图片的 `data-original` 还原成真实地址,相对链接补全为绝对地址 - 面板会提示「该页面已在本机收藏 N 次」 - 可填笔记与标签,可选是否下载图片(离线阅读) - 工具栏「收藏本页」按钮 与 `Ctrl+D` 等价于点击悬浮按钮 ### 收藏夹 - 本地 SQLite 存储,支持按标题 / 正文 / 笔记 / 作者 / 链接全文搜索,按标签筛选 - 内置阅读器:还原排版、代码块、引用、表格样式 - 导出为 **Markdown** 或 **单文件 HTML** - 重新下载缺失图片、编辑标题/笔记/标签、删除条目(同时清理离线图片) ### AI 摘要(DeepSeek) - 在「AI → AI 设置」里填入 **DeepSeek API Key** 即可启用,支持自定义 Base URL、模型(`deepseek-chat` / `deepseek-reasoner`)、温度、长度上限与提示词 - **收藏文章时自动撰写摘要**:保存入库后立即异步调用 DeepSeek,不阻塞界面 - 摘要以卡片形式展示在阅读页顶部(含所用模型名),并写入导出的 Markdown - 收藏列表会标记「AI 摘要 / 摘要生成中 / 摘要失败」 - 支持单条**重新生成**(工具栏「AI 摘要」/ 右键菜单 / `Ctrl+Alt+S`),以及「AI → 批量补全缺失摘要」 - 失败不会清空已有摘要,状态与原因会显示在状态栏 > 只用 Qt 自带网络栈实现,**不引入任何第三方依赖**;换任何 OpenAI 兼容后端只需改 Base URL 与模型名。 ### 自动分类(参考 zReader 的文件夹式组织) - 收藏时**自动归类**,分类依据是**标签 + 摘要**: 1. **关键词规则优先**:在「AI 设置」里为每个分类配关键词,命中标签(3 分)、标题(2 分)、正文(1 分), 达到阈值就直接归类,**不消耗接口调用**; 2. **AI 兜底**:规则不命中时,把「标题 + 标签 + 摘要 + 正文开头」交给 DeepSeek, 要求只从你的分类清单里选一个,返回 `{category, confidence, reason}` 严格 JSON; 3. **手动优先**:手动指定的分类不会被自动流程覆盖(清空后才会重新自动判定)。 - 分类清单与关键词规则都可在「AI 设置 → 自动分类」里改,默认给了一套常用分类: 技术研发 / 产品设计 / 商业财经 / 职场成长 / 生活健康 / 学习阅读 / 社会热点 / 其他 - 「我的收藏」左侧新增**分类筛选(带计数)**,条目名前的 `【分类】` 一眼可见; 阅读页顶部显示绿色分类徽标,鼠标悬停可看到判定来源与理由,Markdown 导出带 `- 分类:…` - 单条:工具栏「自动分类」/ 右键「自动分类(重新判定)」/ `Ctrl+Alt+C` - 批量:**AI → 批量自动分类**,只处理还没分类的条目 --- ## 快速开始 开发环境用 [uv](https://docs.astral.sh/uv/) 管理,依赖声明在 `pyproject.toml`,版本锁定在 `uv.lock`。 ```bash # 1. 安装 uv(已装可跳过) # Windows (PowerShell) powershell -c "irm https://astral.sh/uv/install.ps1 | iex" # macOS / Linux curl -LsSf https://astral.sh/uv/install.sh | sh # 2. 同步环境(自动创建 .venv,按 uv.lock 装好 PySide6) uv sync # 3. 运行 uv run zhihu-saver ``` 也可以直接跑脚本: ```bash uv run python main.py # 等价于 uv run python -m zhihu_saver ``` > 不想用 uv 时,`pip install "PySide6>=6.6,<6.9"` 后 `python main.py` 亦可运行。 ### Windows 一键启动 双击仓库根目录的 `run.bat`:脚本会自动挑选运行环境(优先 uv,其次系统 Python)、 按需执行 `uv sync`,然后启动应用;失败时会停住并给出提示。 ```bat run.bat :: 启动应用 run.bat --check :: 只做环境自检,不打开界面 ``` 首次启动会打开知乎首页。**在页面里正常登录一次**,之后登录态会一直保留。 打开任意回答 / 文章页 → 右下角出现「★」→ 点击 → 填笔记标签 → 保存。 切到「我的收藏」标签页即可搜索、阅读、导出。 ### 配置 DeepSeek(可选,用于自动摘要) 1. 到 申请 API Key(形如 `sk-…`); 2. 打开菜单 **AI → AI 设置…**,填入 Key → 点「测试连接」确认连通 → 「保存」; 3. 之后每次收藏都会自动生成摘要。已有收藏可用 **AI → 批量补全缺失摘要** 补齐。 Base URL 填 `https://api.deepseek.com` 即可(程序会自动补上 `/chat/completions`), 也兼容 `https://api.deepseek.com/v1` 这类写法。 > **不填 API Key 也能用自动分类**:关键词规则是纯本地的,收藏时会直接按标签/标题归类; > 只有规则判定不出来时才会去找模型。存量收藏可用 **AI → 批量自动分类** 补。 ### 环境变量(可选) | 变量 | 说明 | | --- | --- | | `ZHIHU_SAVER_HOME` | 数据目录,默认 `./data` | | `ZHIHU_SAVER_DEBUG_JS=1` | 打印页面控制台日志,排查注入问题用 | | `ZHIHU_SAVER_SOFTWARE_RENDER=1` | 强制软件渲染(显卡驱动异常导致黑屏/闪退时用) | | `ZHIHU_SAVER_DEEPSEEK_API_KEY` / `DEEPSEEK_API_KEY` | DeepSeek 密钥,优先级高于界面里的设置 | | `ZHIHU_SAVER_AI_BASE_URL` | 覆盖接口地址(接自建网关 / 中转站时用) | | `ZHIHU_SAVER_AI_MODEL` | 覆盖模型名 | > 环境变量优先级高于「AI 设置」里的值;被环境变量接管的字段在设置窗口里会置灰并给出提示。 --- ## 数据存放 ``` data/ ├─ zhihu_saver.db # 收藏条目(SQLite) ├─ webengine/ # 浏览器用户数据:Cookie / 登录态 / 缓存 ├─ images// # 每条收藏的离线图片 ├─ cache/ # 阅读器临时 HTML(自动清理) ├─ export/ # 导出的 md / html └─ downloads/ # 页面内「下载」的文件 ``` 想要备份或迁移,整个 `data/` 目录拷走即可。所有数据都只存在本机,不经过任何服务器。 --- ## 快捷键 | 快捷键 | 功能 | | --- | --- | | `Ctrl+D` | 收藏当前页面 | | `Ctrl+T` | 新建标签页 | | `Ctrl+W` | 关闭当前标签页 | | `Ctrl+L` | 定位到地址栏 | | `Ctrl+F` | 跳到收藏夹并聚焦搜索框 | | `Ctrl+Alt+S` | 为当前收藏生成摘要 | | `Ctrl+Alt+C` | 为当前收藏重新分类 | | `Ctrl+1` / `Ctrl+2` | 切换「浏览知乎」/「我的收藏」 | | `F5` / `Alt+←` / `Alt+→` | 刷新 / 后退 / 前进 | --- ## 项目结构 ``` pyproject.toml uv 项目清单(依赖 / 入口脚本 / 构建配置) uv.lock uv 锁定的依赖版本(提交进仓库,保证环境一致) run.bat Windows 一键启动(自动 uv sync + 启动应用) main.py 程序入口(等价于 uv run zhihu-saver) zhihu_saver/ ├─ __main__.py 启动逻辑(Qt WebEngine 初始化顺序敏感) ├─ app.py 装配:目录、存储、Profile、服务、主窗口 ├─ main_window.py 主窗口:标签页、菜单、快捷键 ├─ browser.py 浏览器内核:持久化 Profile、多标签、注入调度 ├─ inject.py 注入调度:读取 JS 模板、域名白名单、拼装最终脚本 ├─ inject.js 注入到页面的 JavaScript(悬浮按钮 + 收藏面板 + 内容抽取) ├─ bridge.py QWebChannel 桥:把 Python 对象暴露给页面 JS ├─ service.py 收藏业务:落库 + 异步补齐离线图片 ├─ storage.py SQLite 存储层 ├─ images.py 图片异步下载与本地化(QNetworkAccessManager) ├─ favorites.py 收藏夹界面:列表 / 阅读 / 导出 / 删除 ├─ ai.py AI 配置 + OpenAI 兼容调用 + 摘要 / 分类服务 ├─ ai_settings.py AI 设置对话框(接口、提示词、分类清单与规则、测试连接) ├─ render.py 阅读页与导出文件的 HTML 渲染 ├─ markdown.py 极简 HTML → Markdown 转换 ├─ style.py 全局 QSS 主题与程序图标 └─ paths.py 运行期目录管理 ``` --- ## 实现要点 1. **注入方式**:实测 Qt 6.8 下 `QWebEngineProfile.scripts()` 不会被自动应用到页面 (页面脚本集合始终为空、脚本从不执行),因此改为在 `BrowserView` 的 `loadFinished` 与 `urlChanged`(防抖)时用 `runJavaScript` 注入主世界。 注入脚本幂等,重复调用只会重新挂载按钮。 2. **QWebChannel 客户端**:知乎 CSP 严格,`