JobData/.planning/phases/02-boss/02-RESEARCH.md

6.5 KiB
Raw Blame History

Phase 2: Boss 直聘重写 — 技术研究

研究日期: 2026-03-21
阶段目标: Boss 直聘爬虫完全基于 crawler_core 运行,旧实现可安全停用


1. 现状分析

1.1 crawler_core 现有基础Phase 1 完成)

文件 内容
crawler_core/http_client.py HTTPClient — requests_go + TLS 伪装 + tenacity 重试min=10s + 代理池/隧道代理
crawler_core/base.py Result[T](泛型)、BaseFetcherBaseSearcherparse_response
crawler_core/boss/sign.py BossSign.generate_traceid() — 已完成且有测试

1.2 待迁移的 Boss 层spiderJobs

spiderJobs/platforms/boss/ 下已有:

文件 当前依赖 迁移目标
sign.py 独立实现(与 crawler_core/boss/sign.py 功能相同) 弃用,改为 import crawler_core
client.py spiderJobs.core.http_client.HTTPClient 改为 crawler_core.http_client.HTTPClient
api.py spiderJobs.core.base.ApiResult/BaseFetcher/BaseSearcher 改为 crawler_core.base.Result/BaseFetcher/BaseSearcher
main.py spiderJobs.core.base.BaseFetcher/BaseSearcher 更新 import功能保持不变

1.3 待保留的反爬机制SmartIPManager

boos_api.py 中有 SmartIPManager(代理轮换+本机 fallback这套逻辑已被 crawler_core 的 HTTPClient 代理池简化替代

  • HTTPClient(proxy_pool=...) 自动随机选择代理(每次请求)
  • HTTPClient(tunnel_proxy=...) 每次新建 session效果类似隧道代理的 IP 轮换)
  • tenacity 重试 min=10s 已满足强制延迟要求

结论:不需要将 SmartIPManager 迁移进来crawler_core 已经覆盖了其功能。


2. API 接口清单(已确认)

spiderJobs/platforms/boss/api.py 实现了 4 个接口:

端点 方式
SearchRecJobs /wapi/zpgeek/miniapp/homepage/recjoblist.json GET
GetJobDetail /wapi/batch/requests(批量子请求) POST
GetBrandDetail /wapi/zpgeek/miniapp/brand/detail.json GET
SearchBrandJobs /wapi/zpgeek/miniapp/brand/joblist.json GET

Boss 响应格式与 crawler_core 默认解析不同:

  • Bosscode=0 表示成功,zpData 为业务数据(而非 statusCode/data
  • 需要在迁移后的 api.py 中保留自定义 _parse_boss_response() 函数

3. 迁移差异分析

3.1 ApiResult → Result[T]

spiderJobs.core.base.ApiResultcrawler_core.base.Result[T] 字段对比:

字段 ApiResult Result[T] 兼容?
success
status_code
data
list
count
is_end_page
error

完全兼容,仅需修改 import 路径。

3.2 BaseFetcher._http → BaseFetcher.http_client

旧 spiderJobs 的 BaseFetcher 使用 self._http 引用 HTTP 客户端,而 crawler_core.base.BaseFetcher 使用 self.http_client

api.py 中两处引用需要更新:

  • SearchRecJobs._request(): self._http.get(...)self.http_client.get(...)
  • GetJobDetail.fetch(): client: BossClient = self._httpclient: BossClient = self.http_client
  • SearchBrandJobs._request(): self._http.get(...)self.http_client.get(...)

3.3 BossClient 迁移

client.pyBossClient 继承的是 spiderJobs.core.http_client.HTTPClient,需改为继承 crawler_core.http_client.HTTPClient。两个 HTTPClient 接口完全相同,无结构性差异。

sign.pyspiderJobs 版)与 crawler_core/boss/sign.py 功能完全相同,迁移后 client.py 直接从 crawler_core.boss.sign 导入即可。


4. 测试策略QUAL-03

4.1 测试框架

项目已有:

  • conftest.py 在项目根目录(用于 pytest path 设置)
  • tests/crawler_core/ 已有 41 个签名单元测试Phase 1

建议新增测试目录:tests/boss/,文件:test_boss_client.py

4.2 Mock/Respx 测试(注意事项)

crawler_core 的 HTTPClient 使用 requests_go(非标准 requestsrespx 专门 mock httpx,不适用。

替代方案:使用 unittest.mock.patch

# 正确的 mock 方式
from unittest.mock import MagicMock, patch

def test_search_rec_jobs_success():
    mock_client = MagicMock()
    mock_client.get.return_value = (200, {
        "code": 0, "zpData": {"jobList": [{"title": "测试职位"}], "hasMore": False}
    })
    searcher = SearchRecJobs(client=mock_client)
    result = searcher.search(page_index=1)
    assert result.success
    assert len(result.list) == 1

由于 HTTPClient 是作为依赖注入传入的,直接用 MagicMock() mock 即可,无需 patch 装饰器。


5. 关键词搜索接口说明

当前 SearchRecJobs 只使用 cityCode 过滤,没有关键词搜索参数。

查看 Boss API关键词搜索应使用 /wapi/zpgeek/miniapp/search.json(需要 query 参数)或直接使用 recjoblist 接口配合 query 字段(如果 API 支持)。

推荐方案: Phase 2 保持现有 SearchRecJobs(推荐列表),关键词过滤通过 main.py 的城市映射传入。真正的关键词搜索 API 端点验证留给手动测试阶段确认。


6. 反爬机制验证

Phase 2 成功标准之一是"反爬机制保留",具体验证点:

机制 实现位置 验证方式
随机延迟 10-20s HTTPClient tenacity min=10s 单元测试检查 wait_random_exponential 配置
TLS 指纹伪装 HTTPClient._new_session()TLS_CHROME_LATEST 代码审查(无法 mock TLS 层)
代理轮换 HTTPClient(tunnel_proxy=...) 每次新建 session 单元测试确认 _new_session() 被调用
Traceid 注入 BossClient._boss_headers() 单元测试检查请求头包含 Traceid

7. Validation ArchitectureNyquist

暂不适用本阶段Phase 2 是代码迁移,无新功能/新接口,验证维度以单元测试+手动验证为主。


RESEARCH COMPLETE

Phase 2 可以规划。 迁移任务明确,风险低(接口兼容),主要工作量在:

  1. 更新 3 个文件的 importclient.py、api.py、main.py
  2. 修正 2 处 self._httpself.http_client 引用
  3. 新增 mock 测试

预计拆分为 2 个 PLAN

  • Plan 01迁移 client.py、api.py、main.py去除 spiderJobs.core 依赖)
  • Plan 02新增 tests/boss/test_boss_client.py mock 测试