# Boss Zhipin Scraper

> Scrape BOSS直聘 (job listing site) via Chrome CDP. Searches jobs by keyword/city/filters, fetches JD details, outputs structured JSON/CSV with plaintext salary, and can summarize scraped results into a job-market prompt. Use when user wants to search/analyze jobs on BOSS直聘 or zhipin.com.

- Skill: `eatmoreduck/boss-zhipin-scraper` (Agent Skill, multi-file: 12 files)
- Install (CLI): `npx skillmds@latest add eatmoreduck/boss-zhipin-scraper`
- Raw SKILL.md: https://api.skillmd.com/api/skills/eatmoreduck/boss-zhipin-scraper/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- License: MIT
- Author: eatmoreduck (https://skillmd.com/u/eatmoreduck)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/eatmoreduck/boss-zhipin-scraper

---


# BOSS直聘职位抓取工具 v2.2

通过 Chrome CDP 协议抓取 BOSS直聘 (zhipin.com) 职位数据，输出结构化 JSON/CSV（含明文薪资），并可对已抓取结果生成聚合摘要和求职材料优化提示词。

## 前置条件

- Chrome 浏览器已安装
- Python 3.10+
- 用户已登录 zhipin.com（或愿意手动登录）

## 脚本位置

本 skill 的脚本在 skill 目录下：

- `scripts/boss_cdp_raw.py`：抓取主脚本
- `scripts/job_summary.py`：抓取后摘要和提示词脚本

**运行任何命令前，必须先确定脚本的绝对路径。**

用以下方式找到脚本（macOS 自带的 `readlink` 不支持 `-f`，用 Python 解析路径更通用）：

```bash
# 方法 1：已知 skill 安装目录（推荐，macOS/Linux 通用）
SKILL_DIR="$(python3 -c "import os,sys;print(os.path.dirname(os.path.realpath(sys.argv[1])))" "$0")"
SCRIPT_PATH="$SKILL_DIR/scripts/boss_cdp_raw.py"
SUMMARY_PATH="$SKILL_DIR/scripts/job_summary.py"

# 方法 2：搜索 hermes skills 目录
SCRIPT_PATH=$(find ~/.hermes/skills -name "boss_cdp_raw.py" -type f 2>/dev/null | head -1)
SUMMARY_PATH=$(find ~/.hermes/skills -name "job_summary.py" -type f 2>/dev/null | head -1)
```

如果找不到脚本，说明 skill 未正确安装，需要重新安装。

## 依赖安装（首次使用必须执行）

脚本依赖 `websocket-client` 和 `requests`。在用户项目的 venv 中安装：

```bash
uv add websocket-client requests
# 或
pip install websocket-client requests
```

## 自动化流程

当用户要求搜索/抓取 BOSS直聘 职位时，**严格按以下顺序执行**：

### 第 1 步：检查环境

```bash
python3 "$SCRIPT_PATH" --check --cdp-port 9222
```

检查三项：Python 依赖 → CDP 连通性 → 登录态。

- **全部通过** → 跳到第 3 步
- **CDP 不通** → 继续第 2 步
- **依赖缺失** → 先装依赖（见上方依赖安装），再重新 --check
- **未登录** → 告诉用户打开 Chrome 登录 zhipin.com，然后重新 --check

### 第 2 步：启动专用浏览器 CDP（仅在 --check CDP 不通时）

```bash
python3 "$SCRIPT_PATH" --setup-chrome --cdp-port 9222
```

这会自动完成：
1. 创建或复用持久隔离 Chrome profile
   - `~/.boss-zhipin-scraper/chrome-profile`
2. 只关闭使用该隔离 profile 的旧 BOSS CDP Chrome，不关闭用户主 Chrome
3. 以 CDP 模式启动 Chrome（`--remote-debugging-port=9222`）
4. 等待 CDP 端口就绪（最多 30 秒）
5. 打开 BOSS 登录页并等待登录完成，直到搜索接口返回明文 `salaryDesc`

默认不复制主 Chrome 的 Cookie、密码、历史记录或扩展；首次启动和后续重复启动都只是创建或复用该专用 profile。首次使用时告诉用户：请在弹出的 BOSS 专用 Chrome 浏览器中访问 zhipin.com 并登录。脚本会等待登录完成并确认接口能返回明文薪资。该专用 profile 是持久目录，机器重启后登录态仍保留，重复运行 `--setup-chrome` 不会清空它。

仅装 Microsoft Edge（未装 Chrome）的机器，可改用 Edge 启动（与 `--setup-chrome` 共用同一隔离 profile）：

```bash
python3 "$SCRIPT_PATH" --setup-edge --cdp-port 9222
```

仅当用户明确要求从主浏览器手动导入 BOSS 登录态时，可使用：

```bash
python3 "$SCRIPT_PATH" --setup-chrome --copy-login-state --cdp-port 9222
```

`--copy-login-state` 在 `--setup-chrome` 下从主 Chrome 导入、在 `--setup-edge` 下从主 Edge 导入，每次运行都会覆盖隔离 profile 内对应的 Cookie 相关文件；日常启动不要加这个参数。它只复制 `Local State` 和 `Default/Cookies*`、`Default/Network/Cookies*` 这类 Cookie 数据库相关文件，不复制密码库或完整 profile。不要默认使用该参数，也不要告诉用户首次启动会自动导入主浏览器登录态。

等用户确认后，重新运行 `--check` 验证。

### 第 3 步：运行抓取

```bash
# 基础搜索
python3 "$SCRIPT_PATH" --keyword "关键词" --city 城市 --pages 3 --output ~/.boss-zhipin-scraper/job-result/jobs.json

# 带 CSV 输出
python3 "$SCRIPT_PATH" --keyword "关键词" --city 城市 --pages 3 --format csv --output ~/.boss-zhipin-scraper/job-result/jobs.json

# 带详情 + 分析报告
python3 "$SCRIPT_PATH" --keyword "关键词" --city 城市 --pages 3 --detail --max-details 8 --analysis --format csv --output ~/.boss-zhipin-scraper/job-result/jobs.json

# 抓取后摘要 + 求职材料优化提示词（默认读取最新抓取结果）
python3 "$SUMMARY_PATH" --top 15

# 真实浏览器/API smoke test（不写结果文件）
python3 "$SCRIPT_PATH" --smoke-test --cdp-port 9222

# 合并多次抓取（去重）
python3 "$SCRIPT_PATH" --keyword "关键词" --city 北京 --pages 3 --merge ~/.boss-zhipin-scraper/job-result/jobs.json --output ~/.boss-zhipin-scraper/job-result/jobs_merged.json
```

默认输出到 `~/.boss-zhipin-scraper/job-result/` 目录，`--format csv` 会给列表和详情都额外生成 `.csv` 文件。`--smoke-test` 只验证真实 Chrome/CDP 能否拿到 API 明文薪资，不写结果文件。

抓取结束后专用 Chrome 不会自动关闭（默认保留登录态，方便连跑多条）。确认不再使用时收尾：

```bash
# 关闭 BOSS 专用 Chrome（只关隔离 profile，不碰主 Chrome）
python3 "$SCRIPT_PATH" --stop-chrome --cdp-port 9222

# 或：让本次抓取正常结束就自动关闭
python3 "$SCRIPT_PATH" --keyword "关键词" --city 城市 --pages 3 --close-chrome
```

`--stop-chrome` 按 `--user-data-dir` 精准匹配，绝不按端口/进程名 kill，因此不会误伤用户主 Chrome。`--close-chrome` 默认关闭，且只在抓取成功路径触发，异常/登录失败不关闭以保留登录态。

摘要脚本只读取 `boss_jobs_*.json` 和 `boss_details_*.json`，不读取本地简历文件，不引入 PDF 依赖，也不给个人与岗位做分数判断。需要指定文件时使用：

```bash
python3 "$SUMMARY_PATH" \
  --input ~/.boss-zhipin-scraper/job-result/boss_jobs_20260625_1200.json \
  --details ~/.boss-zhipin-scraper/job-result/boss_details_20260625_1200.json \
  --top 15
```

## 参数速查

| 参数 | 默认值 | 说明 |
|------|--------|------|
| `--keyword` | AI Agent | 搜索关键词 |
| `--city` | 上海 | 城市名（中文）或 9 位代码；没传时默认上海，无法识别的城市名会报错退出 |
| `--pages` | 3 | 抓取页数（上限 10，每页 30 条） |
| `--output` | ~/.boss-zhipin-scraper/job-result/... | 列表输出路径 |
| `--detail-output` | ~/.boss-zhipin-scraper/job-result/... | 详情输出路径 |
| `--format` | json | 输出格式: json / csv；csv 同时导出列表和详情 CSV |
| `--detail` | 开启（默认） | 抓取详情页 JD |
| `--no-detail` | - | 不抓取详情页（关闭默认行为） |
| `--max-details` | 全部 | 详情页数量上限 |
| `--analysis` | 关闭 | 输出分析报告 |
| `--allow-dom-fallback` | 关闭 | API 无数据时允许降级 DOM 提取；默认关闭，薪资可能不可信 |
| `--merge FILE` | - | 合并已有 JSON（按 job_id 去重） |
| `--cdp-port` | 9222 | CDP 端口 |
| `--setup-chrome` | 关闭 | 一键启动 Chrome CDP（持久隔离 profile） |
| `--setup-edge` | 关闭 | 一键启动 Microsoft Edge CDP（与 `--setup-chrome` 共用隔离 profile） |
| `--browser` | chrome | 搭配 `--setup-chrome` 选择浏览器（chrome/edge）；与 `--setup-edge` 显式冲突时以 `--setup-edge` 为准并提示 |
| `--copy-login-state` | 关闭 | 手动导入主浏览器（`--setup-chrome` 取主 Chrome、`--setup-edge` 取主 Edge）的 Local State + Cookie 相关文件到隔离 profile；默认、首次启动、重复启动都不复制 |
| `--reset-chrome-profile` | 关闭 | 重建 BOSS 专用 profile，会清除此专用浏览器登录态 |
| `--no-wait-login` | 关闭 | `--setup-chrome` 启动后不等待 BOSS 登录完成 |
| `--login-timeout` | 300 | `--setup-chrome` 等待登录完成的秒数 |
| `--stop-chrome` | 关闭 | 关闭 BOSS 专用 CDP Chrome（按隔离 profile 精准匹配，不碰主 Chrome） |
| `--stop-edge` | 关闭 | 关闭 BOSS 专用浏览器 CDP（与 `--stop-chrome` 共用隔离 profile） |
| `--close-chrome` | 关闭 | 抓取正常结束后自动关闭专用 Chrome（默认不关；异常退出不触发，保留登录态） |
| `--check` | 关闭 | 环境检查 |
| `--smoke-test` | 关闭 | 真实 Chrome/CDP 搜索 API smoke test，不写结果文件 |
| `--version` | - | 查看版本号 |

### 筛选参数

| 参数 | 值 |
|------|-----|
| `--scale` | 301=0-20人 302=20-99 303=100-499 304=500-999 305=1000-9999 306=10000+ |
| `--salary` | 402=3K以下 403=3-5K 404=5-10K 405=10-20K 406=20-50K 407=50K+ |
| `--experience` | 108=在校生 102=应届生 101=经验不限 103=1年内 104=1-3年 105=3-5年 106=5-10年 107=10年+ |
| `--degree` | 209=初中及以下 208=中专/中技 206=高中 202=大专 203=本科 204=硕士 205=博士 |

### 城市代码

全国 100010000 | 北京 101010100 | 上海 101020100 | 广州 101280100 | 深圳 101280600 | 杭州 101210100 | 成都 101270100 | 武汉 101200100 | 南京 101190100 | 厦门 101230200

## 输出格式

### JSON

```json
{
  "keyword": "AI Agent",
  "city": "上海",
  "total": 60,
  "jobs": [
    {
      "job_id": "c4420e8bce3a6e25",
      "title": "AI Agent工程师",
      "salary": "30-60K·15薪",
      "location": "上海·闵行区·虹桥",
      "tags": "5-10年 | 本科",
      "boss_name": "SHEIN",
      "boss_title": "招聘者",
      "company_scale": "10000人以上",
      "company_stage": "D轮及以上",
      "company_industry": "电子商务",
      "skills": "Java | Spring | AI",
      "job_link": "https://www.zhipin.com/job_detail/xxx.html",
      "company_link": "https://www.zhipin.com/gongsi/xxx.html",
      "welfare": "节日福利 | 零食下午茶 | 定期体检"
    }
  ]
}
```

### CSV

`--format csv` 时自动在同目录生成 `.csv` 文件：列表 CSV 跟随 `--output`，详情 CSV 跟随 `--detail-output` 或默认详情 JSON 路径。CSV 使用 UTF-8 BOM 编码，Excel 直接打开无乱码。

## 工作原理

1. 通过 Chrome DevTools Protocol (CDP) 连接到已打开的 Chrome 浏览器
2. 在 BOSS直聘页面内注入 JS，用同步 XHR 调用 `/wapi/zpgeek/search/joblist.json` API
3. API 返回明文 `salaryDesc`（如 `30-60K·15薪`），绕过前端字体反爬
4. 列表 API 保留 `securityId` / `lid` 等上下文，进入详情页时带上这些参数
5. 默认禁用 DOM fallback，避免把字体反爬后的薪资写入结果；只有显式 `--allow-dom-fallback` 才降级
6. 每页 30 条，每页抓完立即写入文件，异常退出不丢数据
7. 按 `job_id`（job_link 的 MD5 哈希前 16 位）去重

## 数据安全策略

`--setup-chrome` 默认使用持久隔离 profile，不软链接、不读取、不复制主 Chrome profile。首次启动和后续重复启动都只会创建或复用 `~/.boss-zhipin-scraper/chrome-profile`，不会清空其中的 BOSS 登录态。setup 会等待登录完成，并用多组关键词/城市 probe，要求搜索接口返回明文薪资；如果一直拿不到 `salaryDesc`，不要继续抓取并把 DOM 薪资当成可信数据。这样 CDP 只暴露 BOSS 专用浏览器里的数据，不影响用户主 Chrome、Gmail、GitHub 等账号。

`--input ... --analysis --no-detail` 会优先加载 `--detail-output`，其次加载与输入列表同目录、同时间戳的 `boss_details_*.json`，最后查找 `~/.boss-zhipin-scraper/job-result` 下最新详情文件。

需要清空 BOSS 专用浏览器登录态时使用：

```bash
python3 "$SCRIPT_PATH" --setup-chrome --reset-chrome-profile --cdp-port 9222
```

## 常见问题

1. **--check CDP 不通** → 运行 `--setup-chrome`
2. **--check 未登录** → 在专用 Chrome 中访问 zhipin.com 登录，或重新运行 `--setup-chrome`
3. **薪资空白** → 通常是未登录、登录态失效或接口未返回 `salaryDesc`；先重新登录，不要优先做字体解密或 DOM fallback
4. **抓取中断** → 重新运行即可，增量写入 + 自动去重
5. **端口占用** → `--cdp-port 9223` 换端口
6. **Chrome 启动失败** → `--cdp-port 9223` 换端口，或用 `--reset-chrome-profile` 重建专用 profile

## 注意事项

- 仅用于个人求职研究
- 单次最多 10 页（300 条），防封号
- 翻页间隔 12-22 秒随机延迟，3 页约 1 分钟
- 详情页每条 10-25 秒，10 条约 3-5 分钟
- BOSS直聘可能更新 API 路径，失效时需更新脚本中 `API_JOB_LIST_PATH` 常量

## 安装本 Skill

本 Skill 需手动安装到 Hermes skills 目录（`hermes skills install` 因网络问题可能失败）：

```bash
# 推荐：curl 一键安装
mkdir -p ~/.hermes/skills/data-science/boss-zhipin-scraper/scripts && \
curl -sL https://raw.githubusercontent.com/eatmoreduck/boss-zhipin-scraper/master/SKILL.md \
  -o ~/.hermes/skills/data-science/boss-zhipin-scraper/SKILL.md && \
curl -sL https://raw.githubusercontent.com/eatmoreduck/boss-zhipin-scraper/master/scripts/boss_cdp_raw.py \
  -o ~/.hermes/skills/data-science/boss-zhipin-scraper/scripts/boss_cdp_raw.py && \
curl -sL https://raw.githubusercontent.com/eatmoreduck/boss-zhipin-scraper/master/scripts/job_summary.py \
  -o ~/.hermes/skills/data-science/boss-zhipin-scraper/scripts/job_summary.py && \
mkdir -p ~/.hermes/skills/data-science/boss-zhipin-scraper/data && \
curl -sL https://raw.githubusercontent.com/eatmoreduck/boss-zhipin-scraper/master/data/city_codes.json \
  -o ~/.hermes/skills/data-science/boss-zhipin-scraper/data/city_codes.json
```

或克隆后手动复制：

```bash
git clone https://github.com/eatmoreduck/boss-zhipin-scraper.git
mkdir -p ~/.hermes/skills/data-science/boss-zhipin-scraper/scripts
cp boss-zhipin-scraper/SKILL.md ~/.hermes/skills/data-science/boss-zhipin-scraper/
cp boss-zhipin-scraper/scripts/boss_cdp_raw.py ~/.hermes/skills/data-science/boss-zhipin-scraper/scripts/
cp boss-zhipin-scraper/scripts/job_summary.py ~/.hermes/skills/data-science/boss-zhipin-scraper/scripts/
mkdir -p ~/.hermes/skills/data-science/boss-zhipin-scraper/data
cp boss-zhipin-scraper/data/city_codes.json ~/.hermes/skills/data-science/boss-zhipin-scraper/data/
```

