This repository has been archived on 2026-08-07. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
kb-skills/.planning/phases/07-login-auth/07-01-PLAN.md
T

6.9 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
07-login-auth 01 execute 1
kb_workflow/auth/__init__.py
kb_workflow/auth/zhihu_login.py
tests/test_auth/__init__.py
tests/test_auth/conftest.py
tests/test_auth/test_qrcode_login.py
true
AUTH-01
truths artifacts key_links
用户可以访问知乎登录页面
系统可以从 Canvas 元素截取二维码图片
二维码图片保存到中间目录
系统可以轮询检测 z_c0 Cookie 判断登录状态
path provides min_lines exports
kb_workflow/auth/zhihu_login.py 二维码登录核心逻辑 100
ZhihuLogin
ZhihuLoginResult
path provides exports
tests/test_auth/test_qrcode_login.py 登录逻辑单元测试
test_login_page_access
test_qrcode_screenshot
test_cookie_detection
from to via pattern
kb_workflow/auth/zhihu_login.py PlaywrightBrowser import from kb_workflow.metadata.zhihu_extractor from kb_workflow.metadata.zhihu_extractor import PlaywrightBrowser
from to via pattern
ZhihuLogin.login_by_qrcode() canvas.screenshot() Playwright element screenshot API canvas.*screenshot
实现知乎二维码扫码登录核心逻辑。

Purpose: 提供二维码登录能力,访问登录页 → Canvas 截图 → 轮询检测 Cookie Output: kb_workflow/auth/zhihu_login.py 模块 + Wave 0 测试脚手架

<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/07-login-auth/07-CONTEXT.md @.planning/phases/07-login-auth/07-RESEARCH.md

From kb_workflow/metadata/zhihu_extractor.py:

class PlaywrightBrowser:
    def __init__(self, headless: bool = True, timeout: int = 30)
    def start(self, cookie: str = None)
    def close(self)
    def goto(self, url: str, wait_until: str = "networkidle")
    def wait_for_selector(self, selector: str, timeout: int = None)
    def query_selector(self, selector: str)
    def evaluate(self, script: str)
    # context 属性可用于获取 cookies
    self.context  # BrowserContext
    self.page     # Page

From kb_workflow/pipeline/config.py:

class KBSettings(BaseSettings):
    intermediate_path: str  # 中间目录路径
    zhihu_cookie: SecretStr  # 知乎 Cookie

From kb_workflow/pipeline/schemas.py:

class StepOutput(BaseModel):
    success: bool
    error_message: Optional[str]
    completed_at: datetime
Task 1: 创建测试模块和 fixtures tests/test_auth/__init__.py, tests/test_auth/conftest.py 创建 Wave 0 测试脚手架:
  1. 创建 tests/test_auth/__init__.py 空文件

  2. 创建 tests/test_auth/conftest.py 包含:

    • mock_browser fixture: 使用 unittest.mock 模拟 PlaywrightBrowser
    • mock_env_file fixture: 使用 tmp_path 创建临时 ~/.kb_env
    • sample_cookies fixture: 返回测试用 Cookie 数据

参考 pytest fixture 模式,确保 mock_browser 可以:

  • 模拟 page.wait_for_selector() 返回 mock canvas
  • 模拟 canvas.screenshot() 返回 bytes
  • 模拟 context.cookies() 返回 Cookie 列表 python -c "from tests.test_auth.conftest import *; print('fixtures loaded')" 测试模块和 fixtures 可被 pytest 加载
Task 2: 实现 ZhihuLogin 核心类 kb_workflow/auth/__init__.py, kb_workflow/auth/zhihu_login.py, tests/test_auth/test_qrcode_login.py - Test 1: login_page_access - 访问登录页成功,URL 正确 - Test 2: qrcode_screenshot - Canvas 截图返回 bytes,保存到正确路径 - Test 3: cookie_detection - 检测 z_c0 Cookie 存在返回 True,不存在返回 False - Test 4: login_timeout - 60秒超时后抛出 TimeoutError - Test 5: cookie_extraction - 登录成功后提取 Cookie 字符串 创建 `kb_workflow/auth/` 模块并实现 ZhihuLogin 类:
  1. 创建 kb_workflow/auth/__init__.py:

    from .zhihu_login import ZhihuLogin, ZhihuLoginResult
    __all__ = ["ZhihuLogin", "ZhihuLoginResult"]
    
  2. 创建 kb_workflow/auth/zhihu_login.py:

    • ZhihuLoginResult Pydantic model: success, cookie_str, qrcode_path, error_message
    • ZhihuLogin 类:
      • LOGIN_URL = "https://www.zhihu.com/signin"
      • CANVAS_SELECTORS = ["canvas.SignIn-qrcode", "canvas[class*='qrcode']", "canvas"]
      • __init__(self, intermediate_path: str, headless: bool = True, timeout: int = 60)
      • async def _find_qrcode_canvas(self) -> ElementHandle - 尝试多个选择器
      • async def _save_qrcode_image(self, screenshot: bytes) -> Path - 保存到中间目录
      • async def check_login_cookie(self) -> bool - 检测 z_c0 Cookie
      • async def get_cookies_str(self) -> str - 提取 Cookie 字符串
      • async def login_by_qrcode(self) -> ZhihuLoginResult - 主流程

使用 tenacity 的 @retry 装饰器实现 60 秒轮询:

from tenacity import retry, stop_after_delay, wait_fixed, RetryError

@retry(stop=stop_after_delay(60), wait=wait_fixed(1), reraise=True)
async def _wait_for_login(self):
    if not await self.check_login_cookie():
        raise Exception("Not logged in yet")

二维码图片路径格式: ~/work/intermediate/zhihu_qrcode_{timestamp}.png

  1. 创建 tests/test_auth/test_qrcode_login.py:
    • test_login_page_access: mock browser.goto 验证 URL
    • test_qrcode_screenshot: mock canvas.screenshot 验证保存
    • test_cookie_detection: mock context.cookies 验证检测逻辑
    • test_login_timeout: mock check_login_cookie 始终返回 False
    • test_cookie_extraction: 验证 Cookie 字符串格式

安装依赖: pip install tenacity pytest tests/test_auth/test_qrcode_login.py -x -v - ZhihuLogin 类可实例化 - 所有单元测试通过 - 二维码截图功能可用 - Cookie 检测功能可用

1. 单元测试全部通过: `pytest tests/test_auth/test_qrcode_login.py -v` 2. ZhihuLogin 类可导入: `python -c "from kb_workflow.auth import ZhihuLogin; print(ZhihuLogin)"` 3. tenacity 依赖已安装: `pip show tenacity`

<success_criteria>

  • Wave 0 测试脚手架就绪 (tests/test_auth/)
  • ZhihuLogin 类实现二维码截图和 Cookie 检测
  • 5 个单元测试全部通过
  • 代码符合现有项目模式 (pydantic, Playwright) </success_criteria>
After completion, create `.planning/phases/07-login-auth/07-01-SUMMARY.md`