## Context 当前项目已有 `lyxy-reader-office` skill 用于解析办公文档,其架构设计成熟,包含统一命令行入口、多解析器回退机制、多功能查询等特性。现在需要创建 `lyxy-reader-html` skill,功能上类似但针对 HTML 内容,同时需支持 URL 下载能力。 **约束条件**: - 与 `lyxy-reader-office` 保持相同的用户体验(参数、输出格式) - 代码完全独立,不复用 `lyxy-reader-office` 的代码 - 参考 `temp/downloader/download.py` 和 `temp/parser/parse.py` 的现有实现 ## Goals / Non-Goals **Goals:** - 创建完整的 `lyxy-reader-html` skill 目录结构 - 实现统一的命令行入口 `parser.py`,支持 URL 和 HTML 文件输入 - 实现下载器模块,按 pyppeteer → selenium → httpx → urllib 优先级回退 - 实现解析器模块,按 trafilatura → domscribe → MarkItDown → html2text 优先级回退 - 实现 HTML 预处理清理和 Markdown 后处理 - 实现与 `lyxy-reader-office` 一致的查询功能(全文、字数、行数、标题、章节、搜索) **Non-Goals:** - 不支持可配置的 HTML 清理选项 - 不支持 JavaScript 渲染开关(默认启用完整下载链) - 不支持正文/全文切换(默认使用解析器的正文提取) ## Decisions ### 1. 目录结构参考 lyxy-reader-office **决策**:采用与 `lyxy-reader-office` 相同的目录结构 ``` lyxy-reader-html/ ├── SKILL.md ├── scripts/ │ ├── parser.py # 统一入口 │ ├── common.py # 公共函数 │ ├── downloader.py # URL 下载 │ ├── html_parser.py # HTML 解析 │ └── README.md └── references/ ├── examples.md ├── parsers.md └── error-handling.md ``` **理由**:保持项目一致性,降低用户学习成本 --- ### 2. 下载器优先级:pyppeteer → selenium → httpx → urllib **决策**:直接采用 `temp/downloader/download.py` 的优先级顺序 - pyppeteer(支持 JS 渲染) - selenium(支持 JS 渲染,作为 pyppeteer 的备选) - httpx(轻量级 HTTP 客户端) - urllib(标准库,兜底) **备选方案考虑**: - httpx → urllib → pyppeteer → selenium(速度优先) - 选择保持原顺序,因为 JS 渲染能力对许多现代网页很重要 --- ### 3. 解析器优先级:trafilatura → domscribe → MarkItDown → html2text **决策**:采用精简后的 4 个解析器,顺序参考 `temp/parser/parse.py` 1. trafilatura - 专门用于网页正文提取,质量高 2. domscribe - 专注内容提取 3. MarkItDown - 微软官方,格式规范 4. html2text - 经典库,作为兜底 **备选方案考虑**: - 保留原 6 个解析器(增加 markdownify 和 html-to-markdown) - 选择精简为 4 个,减少维护复杂度 --- ### 4. HTML 预处理清理默认开启且不可配置 **决策**:解析前固定执行 HTML 清理,移除 script/style/link/svg 标签和 URL 属性 - 使用 `temp/clean_html.py` 的清理逻辑 - 不提供 `--no-clean` 参数 **理由**:简化设计,减少用户选择负担 --- ### 5. Markdown 处理函数独立实现 **决策**:在 `common.py` 中独立实现以下函数,不复用 `lyxy-reader-office`: - `remove_markdown_images()` - 移除图片标记 - `normalize_markdown_whitespace()` - 规范化空行 - `extract_titles()` - 提取标题 - `extract_title_content()` - 提取章节内容 - `search_markdown()` - 正则搜索 **理由**:保持 skill 之间完全隔离 --- ### 6. 命令行参数与 lyxy-reader-office 保持一致 **决策**:支持以下参数,与 `lyxy-reader-office` 完全一致: - (无参数):全文输出 - `-c` / `--count`:字数统计 - `-l` / `--lines`:行数统计 - `-t` / `--titles`:提取标题 - `-tc ` / `--title-content `:提取章节 - `-s ` / `--search `:正则搜索 - `-n ` / `--context `:搜索上下文行数 **不添加** HTML 专用参数 **理由**:统一用户体验 ## Risks / Trade-offs | 风险 | 影响 | 缓解措施 | |------|------|----------| | pyppeteer/selenium 依赖重,安装困难 | 中 | 提供 httpx/urllib 作为轻量备选 | | trafilatura 可能提取不到正文 | 低 | 后续解析器会继续尝试 | | 不同解析器输出质量差异大 | 中 | 用户可通过安装不同依赖来间接选择解析器 | | URL 下载超时或被反爬 | 中 | 多下载器回退增加成功率 | ## Migration Plan 不适用 - 这是新 skill 创建,无迁移需求。 ## Open Questions 无 - 所有决策已明确。