JSearch(Google for Jobs,RapidAPI)
通道 jsearch 通过 JSearch API 取 Google for Jobs 聚合的岗位,补充 LinkedIn 和 ATS 之外的、尤其是只发在公司官网的岗位。它属于聚合源(家族 google,原帖链接优先级 4):同一个岗位在别的通道里有更高优先级的链接时,以那个为准;但岗位本身的原帖链接(“查看原帖”打开的链接)会先在 JSearch 返回的多个链接里挑最好的(见下)。
账号与 key
Section titled “账号与 key”- 在 RapidAPI 订阅 JSearch(https://rapidapi.com/letscrape-6bRBa3QguO5/api/jsearch,供应商 OpenWeb Ninja)。免费档每月 200 次请求(硬上限,不绑卡);付费档见套餐页(Pro 10000 次/月,超出每次 $0.003,写文时的价格)。
- 把 RapidAPI 的 key 写进
.env:JSEARCH_API_KEY=...(.env已 gitignore,不要提交、不要贴到聊天或日志里)。 - 在
data/config/sources.yaml把sources.jsearch.enabled改成true(或在设置页的“通道”标签里打开)。 - 没有 key 时通道在
/sources显示“未配置”,一个请求也不发,也不算失败。
配置(data/config/sources.yaml → sources.jsearch)
Section titled “配置(data/config/sources.yaml → sources.jsearch)”| 键 | 含义 |
|---|---|
enabled |
开关(默认关) |
api_base_url |
https://jsearch.p.rapidapi.com;它的域名同时作为 X-RapidAPI-Host |
country / language |
country=de;language 留空 = 该国主要语言 |
pages_per_query |
num_pages:每个查询读几页(每页 10 条,每页算一次请求) |
keywords_per_query |
每个关键词组取前几个词各查一次(Google for Jobs 没有可靠的 OR)。默认 1 |
monthly_request_limit |
套餐每月包含的请求数(免费档 200);用量按“请求数”记在通道的月用量里(/sources 的进度条),用完后通道不再发请求 |
overage_cost_per_request_usd |
超出 monthly_request_limit 后每次请求的价格;0 = 超出后一律不发。大于 0 时按这个价格计入 monthly_budget_usd,预算不够就停 |
monthly_budget_usd |
只计超出 monthly_request_limit 之后的花费(不能超过 paid_total_monthly_budget_usd) |
pace_requests |
把月请求数按日历均摊(月初第 N 天最多用 ceil(limit × N / 当月天数) 次),避免月初几轮把额度用完 |
fetch_details / max_details_per_query |
搜索结果没有正文时才取 /job-details(一次最多 20 个 id,每个 id 算一次请求)。默认关 |
apply_publisher_preference |
没有官网直链时,原帖链接(“查看原帖”打开的链接)按这个发布者顺序挑(不区分大小写,子串匹配),不在表里的排最后 |
rate_limit_retries |
每秒 / 每分钟限流(429)后最多再试几次,每次先等一个 throttle 间隔 |
throttle、max_results |
与其他通道相同 |
- 每个查询 =
search.yaml的一个关键词组 × 一个城市(或远程)。请求:GET /search?query=<关键词> in <城市>&page=1&num_pages=N&country=de&date_posted=today|3days|week|month;远程查询不带城市,加work_from_home=true。date_posted取能覆盖回看窗口的最小档(≤24h today,≤72h 3days,≤168h week,其余 month)。 - 默认一轮 = 3 个关键词组 × (2 个城市 + 远程) = 9 次请求。免费档每月 200 次,所以默认只查每组第一个关键词,并按月均摊;想多查就升级套餐,再调大
keywords_per_query和monthly_request_limit。 - 响应兼容两种信封:RapidAPI
/search的data: [...]和 OpenAPI 文件里/search-v2的data: { jobs: [...] }。没有job_id的记录丢弃,缺标题 / 公司的记录原样入库、由流水线标parse_failed。 - 原帖链接(“查看原帖”打开的链接):直链优先——API 标
is_direct、域名是雇主官网(含子域名)、或官方 ATS 看板地址(Greenhouse / Lever / Ashby / Personio / SmartRecruiters);其余按apply_publisher_preference排序,再按 API 顺序。链接里的utm_*、gclid等追踪参数会去掉(原始记录不动)。sourceUrl是第一发布者的岗位页(它 404 表示岗位已下线),不是 Google 的面板链接。详情页的“查看原帖”对 JSearch 来源优先用上面挑出的链接(apply_url),不用第一发布者的岗位页;这和公司 ATS 来源相反(ATS 优先岗位页,避免打开申请表单)。 - 薪资:
job_min_salary/job_max_salary/job_salary_period;API 不带币种,从薪资文字里的 € / £ / $ / CHF / EUR 等识别(也接受job_salary_currency);识别不出就只保留文字、不给结构化薪资(不推测)。 - 远程:
job_is_remote: true→remote;AI 增强字段work_arrangement存在时优先用;false只说明“不是全远程”,记为unknown。 isAgency不填(JSearch 不说明);中介判断由流水线的agency_names规则做。
- 一次请求(一页)= 1 条用量;失败的请求不记。成功后才记账,所以 5xx 重试不会多记。
429:响应体(或x-ratelimit-requests-remaining: 0)说月配额用完 → 不重试,立即熔断(circuit_breaker.cooldown_hours后试探一次)并走现有的“通道已熔断”Telegram 告警;说每小时 / 每天限额 → 不重试,本轮不再试,计一次失败;其他(每秒限流)→ 等一个 throttle 间隔后重试rate_limit_retries次,仍失败算一次可重试失败。401/403(key 无效或没订阅 JSearch)→auth_expired,触发“凭据失效”告警。- 月用量用完 / 按月均摊的份额用完 →
budget_exceeded,这一轮剩下的查询跳过;不算失败、不熔断。 - 月用量按日历月(
schedule.yaml的时区)统计,RapidAPI 按订阅日起算的计费月可能不同:以 RapidAPI 面板为准,必要时调monthly_request_limit。
pnpm smoke:jsearch # 读 .env;一个查询 = 1 次请求pnpm exec tsx --env-file=/path/to/.env scripts/smoke-jsearch.ts --remote不写数据库,用量只在输出里显示,不计入当月累计。也可以用 pnpm cycle:run --channel jsearch --dry-run(一轮 9 次请求)。
- 供应商新文档(https://www.openwebninja.com/api/jsearch)把
/search-v2(游标分页,x-api-key头,域名api.openwebninja.com)列为当前搜索接口;本通道走 RapidAPI 的/search。字段名两者一致。要切到直连,需要改认证头和分页,属于单独的改动。
本页同步自产品库 Joevonlong/job-radar@2947f47 的 docs/。Job Radar 与任何招聘网站均无关联。代码采用 AGPL-3.0-only 许可。