11 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, user_setup, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | user_setup | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 09-pipeline-integration | 01 | execute | 1 |
|
|
true |
|
|
Cookie 过期处理:Cookie 过期时自动触发扫码登录,用户扫码后流程继续。 新爬虫失败时直接报错,不降级到旧版。 评论爬取默认开启,评论追加到正文末尾。 幂等执行:通过 IdempotencyChecker 确保同一内容不会重复处理。
<execution_context> @/home/starmen1265/.claude/get-shit-done/workflows/execute-plan.md @/home/starmen1265/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/08-crawler/08-03-SUMMARY.md@.planning/phases/09-pipeline-integration/09-RESEARCH.md @.planning/phases/09-pipeline-integration/09-CONTEXT.md
@.planning/phases/09-pipeline-integration/09-00-SUMMARY.md
From kb_workflow/pipeline/platforms/base.py:
class PlatformAdapter(ABC):
@abstractmethod
def get_content_type(self, url: str) -> str:
pass
@abstractmethod
async def fetch_metadata(self, content_id: str, content_type: str, source_url: str = None) -> Dict[str, Any]:
pass
@abstractmethod
async def fetch_content(self, content_id: str, content_type: str, source_url: str = None) -> str:
pass
@abstractmethod
def get_output_filename(self, content_id: str, content_type: str, suffix: str) -> str:
pass
From kb_workflow/crawler/models.py:
class CrawlResult(BaseModel):
success: bool
content_type: str
data: Optional[Union[AnswerData, ArticleData]]
comments: Optional[List[CommentData]]
error: Optional[str]
From kb_workflow/crawler/zhihu_crawler.py:
class ZhihuCrawler:
def crawl_answer(self, url: str, include_comments: bool = False) -> CrawlResult:
...
def crawl_article(self, url: str) -> CrawlResult:
...
def crawl_comments(self, content_type: str, content_id: int, include_comments: bool = True) -> CommentsResult:
...
From kb_workflow/auth/zhihu_login.py:
class ZhihuLogin:
def login_by_qrcode(self) -> ZhihuLoginResult:
...
def validate_cookie(self, cookie_str: str = None) -> CookieValidationResult:
...
From kb_workflow/pipeline/idempotency.py:
class IdempotencyChecker:
def is_processed(self, content_id: str, content_type: str) -> bool:
"""检查内容是否已处理"""
...
def mark_processed(self, content_id: str, content_type: str) -> None:
"""标记内容已处理"""
...
保留公共接口不变 (fetch_metadata, fetch_content, get_content_type, get_output_filename)。
关键决策实现(来自 CONTEXT.md):
- 评论爬取默认开启:设置 include_comments=True 作为默认参数
- 评论追加到正文:修改 _format_with_frontmatter 在 content 末尾追加评论(格式见 CONTEXT.md specifics)
- 幂等执行 (PIPE-03):在 fetch_metadata 开头调用 IdempotencyChecker.is_processed(),已处理的内容直接返回缓存结果或跳过
具体修改:
- 移除 ZhihuPlaywrightExtractor 导入,添加 ZhihuCrawler 导入
- 添加
_get_crawler()方法创建和管理 ZhihuCrawler 实例 - 添加
_crawl_with_crawler()方法使用 ZhihuCrawler 进行内容爬取,include_comments=True 为默认值 - 添加
_convert_crawl_result_to_metadata()方法将 CrawlResult 转换为 metadata dict - 添加
_format_comments_section()方法格式化评论为 Markdown - 修改
_format_with_frontmatter()方法:在正文末尾追加评论部分def _format_with_frontmatter(self, ...): content = base_content if comments: content += "\n\n---\n\n## 热门评论\n\n" + self._format_comments_section(comments) return content - 添加
_is_cookie_expired()方法检测 Cookie 过期 - 添加
_trigger_qrcode_login()方法触发扫码登录 - 添加幂等检查:在处理前调用 IdempotencyChecker.is_processed()
- 移除
_extract_with_playwright和_get_extractor方法(不再需要) - 修改
_detect_login_page方法,基于 CrawlResult 检测登录页面 pytest tests/test_platforms/test_zhihu.py -x -v ZhihuAdapter 使用 ZhihuCrawler 作为内容获取 fetch_metadata 返回包含评论的 CrawlResult fetch_content 返回 Markdown 格式内容(含评论追加,格式为 "---\n## 热门评论") 评论爬取默认开启(include_comments=True) 幂等执行通过 IdempotencyChecker 实现
test_cookie_valid_returns_data: Cookie 有效时,爬取正常返回数据test_cookie_expired_triggers_login: Cookie 过期时,触发扫码登录流程test_login_retry_success: 触发登录后重试成功test_login_failure_raises_error: mock _trigger_qrcode_login 返回登录失败
需要 mock:
- ZhihuCrawler.crawl_answer / crawl_article 返回 mock CrawlResult
- ZhihuLogin.validate_cookie 返回过期状态
- ZhihuLogin.login_by_qrcode 返回登录结果 pytest tests/test_platforms/test_zhihu.py -k "test_cookie" -v Cookie 过期自动触发扫码登录的测试用例全部通过
test_comment_formatting_with_comments: 有评论时,格式化为 "## 热门评论" 部分test_comment_formatting_no_comments: 无评论时,不追加评论部分test_idempotent_execution_skips_processed: 幂等检查阻止重复处理同一内容test_different_content_processes_independently: 不同内容 ID 可以独立处理
验证评论格式:
[原回答/文章内容]
---
## 热门评论
1. **@用户A**: 评论内容...
2. **@用户B**: 评论内容...
验证幂等性:
- 首次调用 fetch_metadata 应正常处理
- 再次调用相同 content_id 应跳过或返回缓存 pytest tests/test_platforms/test_zhihu.py -k "test_comment or test_idempotent" -v 评论格式化测试用例全部通过 幂等执行测试用例全部通过
<success_criteria>
- 知乎链接使用新爬虫处理器,无需手动设置 Cookie
- 新处理器与现有 Pipeline 架构完全兼容
- 支持断点续传和幂等执行(通过 IdempotencyChecker 实现)
- 评论爬取默认开启(include_comments=True)
- 评论追加到正文末尾(格式: "---\n## 热门评论") </success_criteria>