Indeed 没有职位搜索 API,普通请求得到的是安全检查页面,而不是职位。Web Unlocker 用真实浏览器打开搜索,返回包含 50 张职位卡片的页面,薪资和评分都在其中,按 1 页计费:1,000 个职位只需 2 美分。
1,000 次免费请求 · 仅成功时计费 · 195+ 个国家和地区 · 适配 Claude
简单介绍一下您的团队,即可获得:
一个 Indeed 搜索页包含 50 张职位卡片,带有薪资、公司评分和发布日期,Web Unlocker 按 1 页计费。Apify 和 Bright Data 上的 Indeed 采集工具则把每个职位各算作一条记录来计费。
一页,50 个职位。
二十页,1,000 个职位。
需要完整描述吗?每个职位自己的页面多一次请求,所以 1,000 个带描述的职位合计 $1.00。按日期、半径、薪资或远程办公切分市场,每个切片就多一页 50 个职位。
1,000 个带完整描述的 Indeed 职位的费用
20 个搜索页面和 1,000 个职位页面,按公布价格计算
Bright Data、Apify 自家的 Indeed Scraper 以及 Apify 上的 Indeed Job Scraper 都把每个职位按一条记录计费:1,000 条记录,按即用即付和免费套餐价格计算。
连续请求一百个 Indeed 页面,不重试:40 个城市的职位搜索、职位页面、公司页面、评价页面,以及四个国家站点。下面是返回的结果和速度。
没有返回的页面计费 $0。
您为页面付费,而不是为尝试次数付费。
按日期排序搜索,或只看最近 24 小时,最新的职位就排在最上面。您的脚本想多频繁就多频繁地请求这一页:每小时检查一次,每天 24 页,每月 $0.71。
职位数据集每月才更新一次。
您的页面就是今天的。
采集 Indeed 无需解析 HTML:Indeed 自己的 JSON 就在每个搜索页面里,50 个职位带有标题、公司、薪资、评分和发布日期。职位页面以同样的方式带有完整描述。
填写上面的表单。密钥会在一个工作日内通过邮件送达。
带 limit=50 的搜索页面可得到 50 个职位,职位详情页可得到完整描述,或选公司的职位标签页,逐页读取。
从页面中截取 results 数组,就得到 Indeed 显示的每个字段,从薪资到发布日期。
pip install requestsGOLOGIN_SCRAPING_API_KEY=your_key python indeed_jobs.pyhttps://parsing.webunlocker.gologin.com/v1/scrapeimport json
import os
import time
from urllib.parse import urlencode
import requests
query = "marketing manager"
where = "Austin, TX"
def scrape(url):
for attempt in range(3):
response = requests.get(
"https://parsing.webunlocker.gologin.com/v1/scrape",
params={"url": url, "geo": "us", "format": "json"},
headers={"apikey": os.environ["GOLOGIN_SCRAPING_API_KEY"]},
timeout=90,
)
page = response.json().get("data", {}).get("html", "") if response.ok else ""
if '"results":[{' in page:
return page
time.sleep(5)
raise RuntimeError("No jobs came back, try again later")
def embedded(page, marker):
start = page.index(marker) + len(marker) - 1
value, _ = json.JSONDecoder().raw_decode(page[start:])
return value
search = "https://www.indeed.com/jobs?" + urlencode({"q": query, "l": where, "limit": 50})
page = scrape(search)
jobs = [
{
"title": job["title"],
"company": job["company"],
"location": job["formattedLocation"],
"salary": (job.get("salarySnippet") or {}).get("text"),
"rating": job.get("companyRating") or None,
"posted": job.get("formattedRelativeTime"),
"sponsored": job.get("sponsored", False),
"url": "https://www.indeed.com/viewjob?jk=" + job["jobkey"],
}
for job in embedded(page, '"results":[')
]
print(json.dumps({"query": query, "where": where, "jobs_on_page": len(jobs), "jobs": jobs}, indent=2, ensure_ascii=False))GOLOGIN_SCRAPING_API_KEY=your_key node indeed-descriptions.mjshttps://parsing.webunlocker.gologin.com/v1/scrapeconst search = 'https://www.indeed.com/jobs?q=registered+nurse&l=Remote&limit=50';
const wanted = 5;
async function scrape(url, marker) {
for (let attempt = 1; attempt <= 3; attempt++) {
const params = new URLSearchParams({ url, geo: 'us', format: 'json' });
const response = await fetch(`https://parsing.webunlocker.gologin.com/v1/scrape?${params}`, {
headers: { apikey: process.env.GOLOGIN_SCRAPING_API_KEY },
});
const page = response.ok ? (await response.json()).data?.html : '';
if (page?.includes(marker)) return page;
await new Promise((resolve) => setTimeout(resolve, 5000));
}
throw new Error(`Nothing came back for ${url}, try again later`);
}
const field = (page, name) => JSON.parse(page.match(new RegExp(`"${name}":("(?:[^"\\\\]|\\\\.)*")`))?.[1] ?? '""');
const text = (markup) => markup.replace(/<[^>]+>/g, ' ').replace(/&/g, '&').replace(/ /g, ' ').replace(/\s+/g, ' ').trim();
const listing = await scrape(search, '"results":[{');
const keys = [...new Set([...listing.matchAll(/"jobkey":"([0-9a-f]{16})"/g)].map((match) => match[1]))];
console.log(`${keys.length} jobs on the search page, reading the first ${wanted} in full`);
for (const key of keys.slice(0, wanted)) {
const job = await scrape(`https://www.indeed.com/m/viewjob?jk=${key}`, '"sanitizedJobDescription"');
const description = text(field(job, 'sanitizedJobDescription'));
console.log(`\n${field(job, 'jobTitle')} at ${field(job, 'companyName')}, ${field(job, 'formattedLocation')} (${description.length} characters)`);
console.log(`${description.slice(0, 280)}...`);
}GOLOGIN_SCRAPING_API_KEY=your_key node indeed-company.mjshttps://parsing.webunlocker.gologin.com/v1/scrapeconst company = 'Amazon.com';
const pages = 5;
async function scrape(url) {
for (let attempt = 1; attempt <= 3; attempt++) {
const params = new URLSearchParams({ url, geo: 'us', format: 'json' });
const response = await fetch(`https://parsing.webunlocker.gologin.com/v1/scrape?${params}`, {
headers: { apikey: process.env.GOLOGIN_SCRAPING_API_KEY },
});
const page = response.ok ? (await response.json()).data?.html : '';
if (page?.includes('"results":[{')) return page;
await new Promise((resolve) => setTimeout(resolve, 5000));
}
throw new Error(`No jobs came back for ${url}, try again later`);
}
function embedded(page, marker) {
const start = page.indexOf(marker) + marker.length - 1;
const token = /"(?:[^"\\]|\\.)*"|[[\]{}]/g;
token.lastIndex = start;
let depth = 0;
for (let match = token.exec(page); match; match = token.exec(page)) {
depth += '[{'.includes(match[0]) ? 1 : ']}'.includes(match[0]) ? -1 : 0;
if (depth === 0) return JSON.parse(page.slice(start, match.index + 1));
}
return [];
}
const jobs = new Map();
for (let start = 0; start < pages * 20; start += 20) {
const page = await scrape(`https://www.indeed.com/cmp/${company}/jobs?start=${start}`);
const fresh = embedded(page, '"results":[').filter((job) => !jobs.has(job.jobkey));
if (fresh.length === 0) break;
for (const job of fresh) {
jobs.set(job.jobkey, { title: job.title, location: job.formattedLocation, salary: job.salarySnippet?.text ?? null, posted: job.formattedRelativeTime });
}
console.log(`page ${start / 20 + 1}: ${fresh.length} new jobs, ${jobs.size} so far`);
}
console.table([...jobs.values()].slice(0, 10));准备好用在自己的搜索上了吗?获取 API 密钥和免费请求额度。
Indeed 没有面向您应用的职位搜索 API,而每个现成的 Indeed 职位采集工具都按每个职位计费。下面是各条路线获取同样 1,000 个职位所需的条件。
| 需要什么 | Indeed API | Apify | Bright Data | |
|---|---|---|---|---|
| 供您的应用使用的职位搜索数据 | 是 | 否 | 是 | 是 |
| 您按什么付费 | 一页 | 无 API | 每个职位 | 每条记录 |
| 1,000 个带描述的职位 | $1.00 | 无 | $0.10 至 $6 | $1.50 |
| 一次请求的职位数 | 50 | 无 | 每次运行最多 1,000 个 | 一条记录 |
| 第 2 页及之后 | 来自您的账户 | 无 | 是 | 是 |
| 公司评价和薪资 | 是 | 否 | 否 | 是 |
| 整个页面的 HTML 或 Markdown | 是 | 否 | 否 | 否 |
| 企业可免费开始 | 是 | 否 | 是 | 是 |
要采集的不只是 Indeed?Web Unlocker 以同样的方式、同样的价格返回任何页面。
Web Unlocker 每次请求返回一页,而 Indeed 只给访客看一页职位,之后就要求登录。再加上 Cloud Browser 获取其余部分:它登录您的 Indeed 账户一次并保持会话,所以第 2 页、第 20 页和第 50 页的打开方式与第 1 页相同,使用同一台设备和同一个住宅 IP。
您的会话是一个仍在运行的浏览器,而不是恢复出来的文件。今晚关闭脚本,明天再打开,Indeed 看到的仍是同一位已登录的访客。
配置文件每次运行都保留它的 Cookie 和住宅 IP,所以 Indeed 看到的是一台笔记本上的同一个人,而不是每翻一页就换一位新访客。
用 Playwright、Puppeteer 或 Claude 驱动:打开搜索,点击下一页,读取卡片,重复。含住宅 IP。
通过 Playwright、Puppeteer 或 Claude 运行。了解 Cloud Browser。
一个账户,一个代理网络,一套生态。按任务需要选择产品。
还要采集其他站点?请查看 Google Maps、Reddit 和 YouTube 采集工具,或全部网页采集工具。
把带有 limit=50 的 Indeed 搜索地址发送给 Web Unlocker。它会用真实浏览器从美国地址打开页面,并连同 Indeed 自己的 JSON 一起返回:50 个职位,带有标题、公司、地点、薪资、公司评分、发布日期和链接。上面的代码正是这样做的。
职位搜索没有。过去返回职位列表的 Publisher API 已经关闭,Indeed 现在的 API 面向的是向 Indeed 发送职位的合作伙伴,例如招聘管理系统。它们都不会向第三方返回搜索结果,所以采集工具读取的是公开页面。
没有任何一个 Indeed API 可以付费或免费获得来读取职位信息。Web Unlocker 附带 1,000 次免费请求,足够获取 1,000 个搜索页面,每页 50 个职位。
Indeed 的条款是为求职的人写的,而它的职位搜索页面是公开的,无需登录即可加载。Web Unlocker 像访客的浏览器一样加载它们并返回页面。您采集什么、如何使用,由您自己决定,请对照适用于您项目的规则自行核对。
职位信息本来就是供人阅读的,采集工具读取的是访客能看到的公开页面。各国规则不同,也取决于您如何使用这些数据,所以请对照规则核对您自己的用法。Web Unlocker 返回页面,其余由您决定。
一种加载招聘网站页面并把职位提取为数据的程序:标题、公司、地点、薪资、日期、描述和链接。在 Indeed 上,加载这一步由 Web Unlocker 完成,各个字段则来自 Indeed 嵌入每个页面的 JSON。
用 requests 库把搜索地址发送给 Indeed 爬虫 API,在页面中找到 results 数组,再用 json 模块加载它。上面的 Python 标签页是一份完整的脚本,已在真实 API 上测试过:一次请求得到 50 个职位。
每个职位自己的页面就带有它。通过 Web Unlocker 打开 indeed.com/m/viewjob?jk= 加上职位密钥:它会以文本和 HTML 返回描述,以及标题、公司、地点和职位类型。每个职位一页,1,000 条描述只需 $0.98。
Indeed 只给访客看搜索的一页,下一页就要求账户。有两种办法:按日期、半径、薪资或远程办公切分搜索,每个切片都是新的一页 50 个职位;或者在 Cloud Browser 里打开 Indeed,登录您自己的账户一次,然后在这个会话里逐页翻看。
和 Indeed 本身一样新。按日期排序,或只看最近 24 小时,页面就会显示标有“Just posted”的职位。按记录出售的职位数据集每周或每月才更新一次,而页面就是今天的页面。
能。公司页面返回它的评分、评价数量和在招职位;评价页面每页返回 20 条评价,带有优点和缺点,逐页读取;薪资页面按职位名称列出薪酬。按职位名称和城市划分的薪资页面同样可用,带有平均值和范围。
能。英国、加拿大、德国和法国的 Indeed 站点以同样的方式返回了搜索页面,出口 IP 所在国家与之匹配。发送该国站点的地址,并在请求中选择地区即可。
Web Unlocker 返回的是页面,而不是表格,所以在您看到之前不会丢失任何内容。把职位转成 CSV 只需几行代码,或者一句提示词:用 Gologin scraping skill 把页面交给 Claude,让它输出 CSV。
Indeed 爬虫 API 每 1,000 个页面低于 $1,每个页面价格相同。一个搜索页包含 50 个职位,所以来自搜索页的 1,000 个职位只需 2 美分,带完整描述的 1,000 个职位约 $1。页面加载失败不收费。套餐每月 $49 起,含 50,000 次请求。
有,可以免费开始:Web Unlocker 附带 1,000 次免费请求,足够从搜索页面获取 50,000 个职位,或 1,000 条完整的职位描述。
这取决于您的需求。Apify 的 Indeed 采集工具和 Bright Data 出售整理好的现成数据行,并按每个职位计费,它们的用户反映,运行返回的职位比 Indeed 显示的要少。Web Unlocker 是一个以单一价格返回整个页面的 Indeed 网页爬虫,页面里带有 Indeed 自己的 JSON,所以保留哪些字段由您决定。
简单介绍一下您的团队,即可获得: