校招官网 JD 抓取
什么时候用
- 用户要「真实的」岗位列表 / JD 原文,不接受第三方汇总站或概括性描述
- 用户抱怨之前给的岗位数据是假的
- 需要跨多家公司批量获取「岗位名 + 工作城市 + JD 逐条原文 + 任职要求」
为什么不能直接 WebFetch
国内校招官网(腾讯 / 字节 / 美团 / 百度 / 快手 / 京东 / 蚂蚁 / 小红书…)全部是 JS 单页应用。
curl 或 WebFetch 只能拿到一个空壳 <div id="app">,看不到任何岗位。
必须先用真浏览器渲染,再想办法拿数据。
标准流程
Step 1 — 渲染页面(加载 agent-browser skill)
agent-browser open "https://<公司校招官网>/campus/position"
agent-browser wait --load load # 不要用 networkidle,SPA 永不 idle,会挂住
agent-browser get url # 确认真的跳转成功,出现过 about:blank 就是没加载上
Step 2 — 找接口(关键一步)
agent-browser eval "JSON.stringify(performance.getEntriesByType('resource').map(r=>r.name).filter(n=>/api|position|job|search|query/i.test(n)&&!/\.(js|css|png|jpg|svg|woff|webp|gif|ttf)/i.test(n)).slice(-25))"
performance.getEntriesByType('resource') 能列出页面加载过的所有请求,
按 /api|position|job|search/ 过滤,通常一眼就能看到岗位列表接口和详情接口。
如果列表是懒加载的,先在页面上点一下「搜索」或滚动一屏,再执行这条命令。
Step 3 — 试探参数 → 批量拉取
先看请求方式,再猜 body:
curl -s -X POST "<接口>" -H 'Content-Type: application/json' \
-H 'Referer: <官网>' -H 'User-Agent: Mozilla/5.0 ...' -d '{"pageIndex":1,"pageSize":100}' | head -c 500
- 返回
{"message":"请求方式不正确!"}→ 换个方法(GET/POST) - 返回岗位数组 → 成功,改用 python 写循环批量拉
- 分页参数常见写法:
pageIndex/pageSize、pageNum/pageSize、offset/limit、page/limit - pageSize 常有上限(腾讯 1000,超了报 400)
- pageNum 不一定生效(美团就是永远返回同一页)→ 发现「翻页拿到重复数据」时,说明这个站的列表只能靠 UI 筛,别硬刚分页
拿列表 → 逐个取 details → 落 JSON,最后再生成 markdown。
Step 4 — 反爬站点改用 URL 参数
字节跳动的接口带 _signature(JS 现算的签名),
在页内 fetch 同样会被拒(返回 HTML 而不是 JSON)。
绕过方式:列表页支持把筛选条件写在 URL 里,直接导航再读 DOM:
agent-browser open "https://jobs.bytedance.com/campus/position?keywords=%E4%BA%A7%E5%93%81"
sleep 2
agent-browser eval "document.body.innerText.slice(0,3000)" # 读 JD 正文
agent-browser eval "JSON.stringify([...document.querySelectorAll('a')].filter(a=>/\/position\/\d/.test(a.getAttribute('href')||'')).map(a=>a.innerText.replace(/\n+/g,' | ').slice(0,110)+' || '+a.getAttribute('href')))" # 拿岗位名 + 详情链接
Step 5 — 收尾
agent-browser close --all
务必执行。 漏掉会留僵尸 Chromium 进程吃内存。
已知接口速查(2026-09 实测)
| 公司 | 接口 | 参数 |
|---|---|---|
| 腾讯 | POST https://join.qq.com/api/v1/position/searchPosition |
{"pageIndex":1,"pageSize":1000,"keyword":"产品"},pageSize≤1000 |
| 腾讯(详情) | GET https://join.qq.com/api/v1/jobDetails/getJobDetailsByPostId?postId= |
字段 desc / request(不是 require)/ graduateBonus |
| 美团 | POST https://zhaopin.meituan.com/api/official/job/getJobList |
必带 campusHiringType(1=应届生 / 2=转正实习 / 6=日常实习);pageNum 无效 |
| 美团(枚举) | GET https://zhaopin.meituan.com/api/official/job/search/enum?enumType=JF |
岗位族;产品类 = 11002;enumType=CAMPUS_HIRING 取招聘类型 |
| 字节 | 无签名不可用 → 走 https://jobs.bytedance.com/campus/position?keywords=产品 |
— |
| 得物 | 与字节同一套 ATS 平台 → 走 https://campus.dewu.com/578078/position/list?keywords=产品 |
列表页渲染出 JD 全文 |
| 米哈游 | POST https://ats.openout.mihoyo.com/ats-portal/v1/job/list |
参数名是 channel(不是 pageIndex);详情接口需登录,改用列表页 DOM |
坑与教训
timeout命令 macOS 没有(是gtimeout),别在命令里写timeout 120 ...,会 command not found。- 一条 bash 里串太多命令会被 SIGKILL(exit 137)。把「打开页面」和「读取内容」拆成两条命令。
agent-browser get url返回about:blank= 页面根本没加载上,别继续往下做,重开。- JS 文本里中文的引号是
"""",直接塞进 shell 双引号字符串会出问题 → 用 python 写脚本文件,别用-c拼超长命令。 - 不要把第三方汇总站(求职机构公众号、简历站)的 JD 当原文用,它们会改写、会过期。要么官网原文,要么明确标注为二手来源。
- 抓完必须核对:工作城市和专业要求是求职者最容易被误导的两栏,务必逐条抄原文。
- hash 路由的详情页在无头浏览器里经常渲染失败(
document.documentElement.innerText.length === 0, 但outerHTML.length有值 = 页面只剩骨架)。表现:列表页正常、详情页空白、reload 也无效。 → 别死磕,回头读列表页的 DOM(很多站列表项里就带 JD 全文),或改用官方岗位页的转载补详情。 - React 站的筛选器用 JS
.click()常常无效(要触发框架的合成事件)。 可靠做法:agent-browser find text "<筛选项>" click,再用document.body.innerText.match(/职位列表\((\d+)\)/)核对数量有没有变 —— 数量没变就是没点上。 - 想拿 POST 请求体时,monkey-patch
fetch+XMLHttpRequest再触发一次操作是可行的, 但要先确认请求真的走 XHR/fetch(有些站用 axios 的 adapter 或先于 patch 发出,就会抓不到)。
输出建议
产物写成一份 markdown 报告,每家公司包含:
- 官方入口 URL + 毕业时间窗口 + 投递规则(能投几个志愿 / 顺序 / 是否可改)+ 笔试规则
- 岗位清单表:
岗位名 | 工作城市 | 是否卡专业 - 每个核心岗:
岗位描述(逐条原文)/任职要求(逐条原文)/专业要求(原话)/来源 URL - 最后附「待扒清单」,没抓到的写「未获取到」,绝不编