Craigslist 目前在约 700 个本地站点上每月仍能带来大约 ——但它依然没有公开 API。如果你想从那些公寓房源、二手车、招聘信息或零工广告里拿到结构化数据,抓取几乎就是唯一选择。
不过,Craigslist 自家的反爬系统非常严格。它不用 Cloudflare,也不用 DataDome,而是采用了自己基于 nginx 的限流机制,而且已经打磨了十多年。只要请求方式不对,你第二杯咖啡还没喝完,可能就已经收到一个干脆利落的 403。我花了大量时间测试 Craigslist 的各种防护策略,这篇指南就是这些经验的总结:一份适用于 2025 年、覆盖所有分类的 Python 教程,内容包括 JSON-LD 抽取方法(相比过时教程,这是最大的提升)、真实有效的防封策略、法律风险分析,以及一个无需写代码的替代方案,适合只想拿到数据、不想动手写一行代码的人。
用 Python 抓取 Craigslist 到底是什么意思?
用 Python 抓取 Craigslist,指的是通过脚本程序化访问 Craigslist 页面,提取你关心的结构化数据——比如标题、价格、描述、图片、位置、发布时间——并把它保存到表格、数据库或 JSON 文件中。
Python 之所以是首选语言,是因为它的库生态非常成熟。借助 requests、BeautifulSoup、lxml 和 curl_cffi,你可以在 100 行以内写出一个可用的 Craigslist 爬虫。社区也非常庞大,所以当 Craigslist 发生变化时(它确实会变),通常早就有人把解决方案找出来了。
最关键的一点是:Craigslist 。它唯一正式提供的程序化接口是 Bulk Posting Interface(BAPI),而且它只是写入接口——只允许经过批准的付费发布者提交信息,不能用来读取数据。你在第三方平台上看到的任何“Craigslist API”产品,本质上都是非官方爬虫,而不是 Craigslist 授权的接口。如果你需要批量数据,就只能自己抓取。
为什么要抓取 Craigslist?真实应用场景有哪些?
Craigslist 不只是一个买二手沙发的平台。它其实是一个覆盖多个垂直领域、持续更新的大型数据源。下面这些人最能从中受益:
| 应用场景 | 受益人群 | 提取内容 |
|---|---|---|
| 公寓与租金监测 | 房产经纪人、租客、PropTech 公司 | 价格、面积、卧室数、街区、经纬度 |
| 二手车市场分析 | 车商、消费者应用、研究人员 | 价格、品牌、车型、年份、里程、车况 |
| 招聘市场研究 | 招聘人员、劳动经济学者、劳动力分析师 | 职位标题、薪资、雇佣类型、发布时间 |
| 线索开发 | 销售团队、服务商 | 联系方式、公司名称、服务区域 |
| 竞争定价分析 | 本地服务商、电商运营团队 | 服务价格、描述、覆盖区域 |
最常被引用的学术案例之一是 ——大约 50 万条美国二手车信息,包含 26 个变量,已经成为几十篇论文的基础,其中包括一篇 2024 年在 ResearchGate 上发布的美国二手车市场动态研究。对冲基金也曾购买聚合后的 Craigslist 租金数据,用于研究租金趋势。销售团队则经常抓取服务和零工分类,用来获取潜在客户。
数学很简单:手工复制粘贴 8 小时 vs. 一个设计良好的爬虫大约 10 分钟。

用 Python 抓取 Craigslist:不只是汽车,所有分类都能抓
我见过的几乎所有 Craigslist 教程都只讲二手车分类——这就像写一篇 Google 教程却只讲图片搜索一样。Craigslist 有几十个分类,而且每个分类的 URL 规则都不一样。
其结构通常是:https://{city}.craigslist.org/search/{category_slug}
只要替换城市子域名和分类 slug,你抓到的就是完全不同的垂直板块。下面是最常见分类的参考表(已于 2025 年 4 月核实):
| 分类 | URL Slug | 通常提取的字段 |
|---|---|---|
| 公寓 / 房源 | /search/apa | 价格、面积、卧室数、位置、宠物政策 |
| 汽车与卡车 | /search/cta | 价格、品牌、车型、年份、里程 |
| 招聘 | /search/jjj | 标题、公司、薪资、雇佣类型 |
| 服务 | /search/bbb | 标题、描述、电话号码、区域 |
| 零工 | /search/ggg | 标题、报酬、日期、分类 |
| 出售物品(通用) | /search/sss | 标题、价格、成色、位置 |
你也可以叠加查询参数来做筛选:
| 参数 | 用途 | 示例 |
|---|---|---|
query | 全文关键词搜索 | ?query=studio |
min_price / max_price | 价格区间 | &min_price=1500&max_price=3000 |
hasPic | 只显示带图片的帖子 | &hasPic=1 |
postedToday | 最近 24 小时发布 | &postedToday=1 |
sort | 排序方式 | &sort=priceasc |
s | 分页偏移量(每页 120 条) | ?s=120 |
所以像 https://newyork.craigslist.org/search/apa?min_price=1500&max_price=3000&hasPic=1 这样的链接,就能拿到纽约地区 1500 到 3000 美元、带图片的公寓信息。本指南里的 Python 爬虫都适用于这些分类——只需要替换 slug 即可。
2025 年 Craigslist HTML 选择器:旧版 vs. 新版(以及 JSON 快捷法)
Craigslist 爬虫最常坏掉的原因,就是 HTML 结构变化。如果你还在照着 2022 年的教程,去抓 .result-row 或 .result-info,那你的爬虫基本已经报废了。
Craigslist 在 2023–2024 年重写了搜索结果的标记结构。旧的 class 名称虽然还被嵌套在新的包装层里,但如果在 DOM 顶层直接抓它们,拿到的就是空列表。变化如下:
| 元素 | 旧版选择器(2024 年前) | 当前选择器(2025 年) |
|---|---|---|
| 列表容器 | .result-info | .cl-search-result |
| 标题链接 | .result-title | .posting-title a |
| 价格 | .result-price | .priceinfo |
| 元信息(区域) | .result-hood | .meta |
但真正的关键洞察——也是 2025 年可用爬虫与过时教程的分水岭——是:你根本不需要解析搜索结果页的 HTML。
Craigslist 现在会把每个可见房源嵌入到 <script id="ld_searchpage_results"> 标签中,以结构化的 JSON-LD 数据形式返回。一次 requests.get() 请求,就能拿到完整的 schema.org ItemList,包含页面上的每一条列表信息——标题、价格、币种、位置、详情页链接、图片 URL。无需 JavaScript 渲染,也没有 CSS 选择器失效的问题。
JSON-LD 的方式更快、更稳定,而且当 Craigslist 调整界面时,它也更不容易出问题。现在仍在维护的 GitHub 项目,几乎都在用这个方法,我们下面的教程也会采用它。
有一个例外:JSON-LD 区块只在里比较常见——比如公寓(apa)、出售物品(sss)、汽车(cta)、房源(hhh)。而招聘(jjj)、零工(ggg)、社区(ccc)和服务(bbb)这些分类里,往往没有内容,或者信息很少,因为这些帖子没有 schema.org/Offer 价格字段。对于这些分类,就需要回退到 .cl-search-result 的 HTML 解析路径。
选择你的 Python 技术栈:Requests + BS4 vs. Selenium vs. Playwright
这是每个爬虫论坛都会问到的问题:“我该用哪个库?”但对于 Craigslist 来说,答案比大多数网站都更明确。
| 因素 | requests + BeautifulSoup | Selenium | Playwright |
|---|---|---|---|
| 速度 | 每秒 5–15 页(受网络限制) | 每秒 0.3–1 页 | 每秒 0.5–2 页 |
| JS 渲染内容 | 否 | 是 | 是 |
| 内存占用 | 约 30–60 MB | 约 400–700 MB | 约 300–500 MB |
| 配置复杂度 | 低 | 中 | 中 |
| 反爬抗性 | 低(需要请求头/代理) | 中(真实浏览器) | 中高 |
| 最适合的 Craigslist 场景 | 搜索结果页(JSON-LD) | 含动态内容的详情页 | 大规模异步抓取 |
| 学习曲线 | 适合初学者 | 中等 | 中等 |
Craigslist 页面是服务端渲染的。JSON-LD 数据块本来就在初始 HTML 中。读取路径上没有 JavaScript 挑战。所有仍在维护的 都使用 requests + BeautifulSoup 或 Scrapy,几乎没有项目会用 Selenium 或 Playwright。这个选择不是巧合——浏览器自动化框架会额外吃掉几百 MB 内存、速度慢 10–100 倍,而且还会带来更明显的指纹,而这些代价换来的收益并不大。
我的建议:
- requests + BS4:从这里开始。它和 JSON-LD 抽取方法天然契合,足以覆盖 95% 的 Craigslist 抓取需求。
- Selenium:只有当你必须与某些详情页上的动态内容交互时才用(在 Craigslist 上这种情况很少见)。
- Playwright:如果你要用异步并发扩展到成千上万的页面,可以考虑它——但说实话,Craigslist 的瓶颈是限流,不是你库的吞吐能力。
如果你想看更完整的比较,我们另外写过 以及 的专题文章。
无代码替代方案:不写 Python 也能抓取 Craigslist
在开始写代码前先插一句——这一部分是给不写程序的人看的。房产经纪人、销售团队、运营经理都适用:如果你只是想要数据,而不想写 Python,那有更快的路径。
是一款以 Chrome 扩展形式运行的 AI 网页爬虫,只需要大约 2 次点击,就能抓取 Craigslist,而且完全不需要代码。流程如下:
- 打开任意 Craigslist 搜索结果页(公寓、汽车、招聘等任意分类都可以)。
- 在 Thunderbit 侧边栏点击 “AI Suggest Fields”。AI 会读取页面,并自动识别标题、价格、位置、链接等列。
- 点击 “Scrape”——几秒钟内就会完成数据提取。
- 使用 Subpage Scraping 逐个访问列表详情页,补充完整描述、电话号码、图片和属性信息。
- 直接导出到 Google Sheets、Excel、Airtable 或 Notion,完全免费。
如果你有周期性需求——比如每天监控房租价格,或者每周抓一份招聘信息快照——Thunderbit 的 Scheduled Scraper 允许你用自然语言描述计划,系统会自动运行。无需 cron 任务,也不用搭服务器。
Thunderbit 还通过 Cloud Scraping 模式自动处理反爬机制,所以你不必操心轮换代理或编写复杂请求头。如果你想试试,可以安装 亲自体验一下。
如果你想要完全的控制权和自定义能力,那就继续往下看 Python 的详细步骤吧。
逐步教程:如何用 Python 抓取 Craigslist(完整指南)
- 难度: 中级
- 所需时间: 约 30 分钟(配置 + 首次抓取)
- 你需要准备: Python 3.8+、Chrome 浏览器(用于检查页面)、终端
第 1 步:搭建 Python 环境
安装所需库:
1pip install requests beautifulsoup4 lxml
lxml 不是必须的,但它能明显加快 BeautifulSoup 的解析速度。如果后面遇到 TLS 指纹识别问题(后面的防封章节会讲),你也可以安装 curl_cffi:
1pip install curl_cffi
你的导入代码如下:
1import requests
2from bs4 import BeautifulSoup
3import json
4import csv
5import time
6import random
现在你应该已经有了一个干净的 Python 环境,所有依赖也都安装完毕。
第 2 步:为任意分类构建 Craigslist URL
使用城市 + 分类 slug + 可选筛选条件,动态生成目标链接:
1from urllib.parse import urlencode
2BASE = "https://{city}.craigslist.org/search/{slug}"
3def build_url(city, slug, **params):
4 return f"{BASE.format(city=city, slug=slug)}?{urlencode(params)}"
5# 示例:纽约公寓,价格 1500–3000 美元,带图片
6url = build_url("newyork", "apa", min_price=1500, max_price=3000, hasPic=1)
7print(url)
8# https://newyork.craigslist.org/search/apa?min_price=1500&max_price=3000&hasPic=1
把 "apa" 换成 "cta"(汽车)、"jjj"(招聘)、"bbb"(服务)或上面分类表中的任意 slug。把 "newyork" 换成 "sfbay"、"chicago"、"losangeles" 等城市即可。
第 3 步:请求页面并提取嵌入的 JSON
发送带有合适请求头的 GET 请求,然后解析 JSON-LD 区块:
1HEADERS = {
2 "User-Agent": (
3 "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
4 "AppleWebKit/537.36 (KHTML, like Gecko) "
5 "Chrome/124.0.0.0 Safari/537.36"
6 ),
7 "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
8 "Accept-Language": "en-US,en;q=0.9",
9 "Accept-Encoding": "gzip, deflate, br",
10 "Referer": "https://www.craigslist.org/",
11 "Sec-Fetch-Dest": "document",
12 "Sec-Fetch-Mode": "navigate",
13 "Sec-Fetch-Site": "same-origin",
14 "Upgrade-Insecure-Requests": "1",
15}
16session = requests.Session()
17r = session.get(url, headers=HEADERS, timeout=20)
18r.raise_for_status()
19soup = BeautifulSoup(r.text, "html.parser")
20tag = soup.select_one("script#ld_searchpage_results")
21data = json.loads(tag.text) if tag else {"itemListElement": []}
如果 tag 是 None,说明该分类没有 JSON-LD 区块——那就回退到 HTML 解析(见上面的选择器表)。对于公寓、汽车和出售物品分类,JSON-LD 区块通常都很稳定。
第 4 步:把列表数据解析成结构化记录
遍历 JSON 项,提取你需要的字段:
1listings = []
2for entry in data["itemListElement"]:
3 item = entry["item"]
4 offers = item.get("offers", {}) or {}
5 addr = (offers.get("availableAtOrFrom") or {}).get("address", {})
6 listings.append({
7 "name": item.get("name"),
8 "url": offers.get("url"),
9 "price": offers.get("price"),
10 "currency": offers.get("priceCurrency"),
11 "locality": addr.get("addressLocality"),
12 "region": addr.get("addressRegion"),
13 "image": item.get("image"),
14 })
15print(f"Found {len(listings)} listings")
你应该会看到类似“Found 120 listings”的输出(Craigslist 每页显示 120 条结果)。有些帖子如果发布者没有填写价格,price 可能会是 None——在后续逻辑里记得妥善处理。
第 5 步:抓取详情页,获取更丰富的数据
搜索结果页只能给你摘要信息。如果你想要完整描述、属性信息(卧室数、面积、宠物政策)、经纬度坐标和图片,就需要访问每条信息对应的详情页。
1def fetch_detail(url, session):
2 r = session.get(url, headers=HEADERS, timeout=20)
3 r.raise_for_status()
4 s = BeautifulSoup(r.text, "html.parser")
5 body = s.select_one("#postingbody")
6 mp = s.select_one("#map")
7 return {
8 "description": body.get_text("\n", strip=True) if body else None,
9 "attributes": [x.get_text(" ", strip=True)
10 for x in s.select("p.attrgroup span, div.attrgroup .attr")],
11 "lat": mp.get("data-latitude") if mp else None,
12 "lng": mp.get("data-longitude") if mp else None,
13 "images": [img["src"] for img in s.select("div.gallery img")],
14 }
15for item in listings:
16 item.update(fetch_detail(item["url"], session))
17 time.sleep(random.uniform(3, 6)) # 关键:加入随机抖动,避免封禁
time.sleep(random.uniform(3, 6)) 这一步不是可选项。跳过它,你可能在几十次请求内就被 403。详情页是服务端渲染的,选择器也很稳定(#titletextonly、#postingbody、#map 这些自大约 2017 年起就没怎么变过)——这大概是 Craigslist 为数不多真正稳定的地方之一。
第 6 步:处理分页,抓取全部结果
Craigslist 使用 ?s=120 偏移参数来分页。每页显示 120 条结果,最大偏移量通常是 2999。
1def iter_all(city, slug, max_pages=25, **filters):
2 for page in range(max_pages):
3 offset = page * 120
4 url = build_url(city, slug, s=offset, **filters)
5 r = session.get(url, headers=HEADERS, timeout=20)
6 r.raise_for_status()
7 soup = BeautifulSoup(r.text, "html.parser")
8 tag = soup.select_one("script#ld_searchpage_results")
9 if not tag:
10 break
11 data = json.loads(tag.text)
12 items = data.get("itemListElement", [])
13 if not items:
14 break
15 for entry in items:
16 item = entry["item"]
17 offers = item.get("offers", {}) or {}
18 yield {
19 "name": item.get("name"),
20 "url": offers.get("url"),
21 "price": offers.get("price"),
22 }
23 time.sleep(random.uniform(2.5, 5.0))
不要试图在短时间内连续抓取成千上万页。Craigslist 的限流是按 IP 计算的,而无论你用什么库,单个 IP 的可持续吞吐量都大概只有每秒 0.3–0.5 个请求。这个上限是 Craigslist 设定的,不是 Python 的问题。
第 7 步:把 Craigslist 数据导出为 CSV、JSON 或 Google Sheets
保存你的结果:
1# CSV
2with open("craigslist.csv", "w", newline="", encoding="utf-8") as f:
3 w = csv.DictWriter(f, fieldnames=listings[0].keys())
4 w.writeheader()
5 w.writerows(listings)
6# JSON
7with open("craigslist.json", "w", encoding="utf-8") as f:
8 json.dump(listings, f, indent=2, ensure_ascii=False)
如果你想彻底跳过导出代码,Thunderbit 可以直接从浏览器免费导出到 Google Sheets、Excel、Airtable 或 Notion。对于 Python 工作流来说,CSV 和 JSON 仍然是标准输出格式。你也可以把数据直接送入 pandas 做分析,或者用 sqlite3 存进数据库。
用 Python 抓取 Craigslist 时,如何避免被封禁
很多教程都会把这一部分轻描淡写地带过。但 Craigslist 的反爬系统是自研的,不是现成方案,而且有一些很特别的细节。

使用真实、完整的请求头
Craigslist 会检查请求头的顺序和完整性。只要缺少 Sec-Fetch-Dest,或者 User-Agent 太旧,请求甚至在到达内容层之前就会被标记。上面第 3 步里展示的完整 Chrome 120+ 请求头,是最低要求。你可以在 5 到 10 个近期的 Chrome/Firefox 桌面端字符串之间轮换 User-Agent——但不要在同一个会话里频繁切换,否则看起来非常不自然。
缺少 Sec-Fetch-* 头,是新手爬虫一上来就被瞬间封掉的最常见原因。
在请求之间加入随机延迟
来自 (ScrapingBee、Scraperly、Oxylabs、Multilogin)的社区共识都指向:搜索结果页请求间隔应为 随机 2–5 秒,详情页请求间隔应为 3–6 秒。固定间隔看起来就像机器人。用 time.sleep(random.uniform(2, 5))——千万别写死成 time.sleep(2)。
规模化抓取时使用代理轮换
Craigslist 会预先封掉整个 AWS、GCP 和 Azure 的 IP 段。数据中心代理通常一上来就失效。如果你要抓几百页以上,就需要 住宅代理轮换,最好每 20–30 次请求更换一次。移动代理的检测风险最低,但价格也最高,大约是 $8–30/GB。
| 代理类型 | 在 Craigslist 上的检测风险 | 费用(2025) |
|---|---|---|
| 数据中心代理 | 非常高——通常首次请求就会被拦 | $0.50–2/GB |
| 住宅轮换代理 | 低——推荐使用 | $5–15/GB |
| 移动代理 | 最低 | $8–30/GB |
如果你不想自己管理这些,Thunderbit 的 Cloud Scraping 模式会自动帮你处理代理轮换。
优雅处理验证码
Craigslist 页面里的验证码并不常见,通常出现在发布或回复流程中,而不是读取页面时。如果真的遇到:至少等待 60 秒、切换 IP、清理 cookies、降低请求速度。持续出现验证码,说明你的抓取节奏太激进,不是靠暴力破解就能解决的谜题。
尊重限流并实现退避机制
当你触发限流时,Craigslist 返回的是 403(不是 429)。403 意味着当前 IP 已经进入黑名单——不要盲目重试。先换 IP、换 UA,再等待。
1from requests.adapters import HTTPAdapter
2from urllib3.util.retry import Retry
3retry = Retry(
4 total=5,
5 backoff_factor=1.5, # 1.5, 3, 6, 12, 24 秒
6 status_forcelist=[429, 500, 502, 503, 504],
7 allowed_methods={"GET"},
8 respect_retry_after_header=True,
9)
10adapter = HTTPAdapter(max_retries=retry)
11session.mount("https://", adapter)
再补充一个技巧:社区反馈一直显示,目标城市当地时间凌晨 2–6 点是最安全的抓取窗口,封禁率比白天低大约 30–40%。
TLS 指纹识别——最隐蔽的陷阱
Craigslist 的机器人检测层会检查 TLS ClientHello。Python 的 requests 库(基于 OpenSSL)所产生的 JA3 指纹,并不对应任何真实浏览器。即便你的 User-Agent 完美无误,只要 TLS 指纹不是浏览器级别,依然会被识别为异常。解决方法是使用 并设置 impersonate="chrome124",让它模拟 Chrome 的 TLS 握手:
1from curl_cffi import requests as cffi_requests
2r = cffi_requests.get(url, headers=HEADERS, impersonate="chrome124")
如果你在使用干净的住宅 IP、正确请求头的情况下仍然频繁遇到 403,那大概率就是 TLS 指纹惹的祸。
Craigslist robots.txt、服务条款与负责任抓取
大多数教程要么完全不提这一点,要么只在 FAQ 里随便带过一句。考虑到 Craigslist 曾在 ,这件事显然不该只当脚注处理。
Craigslist 的 robots.txt 到底写了什么
其实非常短。它只有一个 User-agent: * 区块,并且只禁止了 7 个路径:
1Disallow: /reply
2Disallow: /fb/
3Disallow: /suggest
4Disallow: /flag
5Disallow: /mf
6Disallow: /mailflag
7Disallow: /eaf
这 7 个都是交互式或会修改状态的端点:回复、举报、建议、发送邮件给朋友等。列表页面(/search/...、单条帖子 URL)并没有被禁止。 虽然没有 Crawl-delay 指令,但 Craigslist 还是通过 IP 封锁来执行限速。
城市子站点还会公开 sitemap,比如 https://newyork.craigslist.org/sitemap/index.xml,这是官方可发现列表内容的路径。
法律先例:几个真正重要的案件
Craigslist v. 3Taps(2013 年,2015 年和解): 3Taps 抓取 Craigslist 的房源信息并转售。当 Craigslist 发出停止侵权通知并封掉其 IP 后,3Taps 通过轮换代理绕过封锁。法院认定,在明确撤销授权后继续绕过 IP 封锁,构成 CFAA 所说的“未经授权”。3Taps 。
Meta v. Bright Data(2024): 这一更近的判决认为,Meta 的服务条款不能禁止对公开可访问数据进行已登出的抓取。法院认定,已登出的抓取者“与普通访客处于同一位置”。这对 2024–2025 年的爬虫来说是最重要的判例之一——如果你从不创建 Craigslist 账号、不登录,只访问公开可见页面,那么服务条款未必能作为合同对你强制执行。
实际结论: 在 Van Buren(2021)和 hiQ v. LinkedIn(2022)之后,对于公开可访问页面,CFAA 风险已明显下降。但州法上的侵权主张(如动产侵占、挪用)仍然存在——这也是 3Taps 和 6050 万美元 RadPad 判决背后的核心原因。
以上内容仅供信息参考,不构成法律建议。如果你要商业化抓取 Craigslist,最好咨询律师。
负责任抓取的实用清单
- ✅ 遵守 robots.txt 中的每一条
Disallow,尤其是这 7 个操作端点 - ✅ 每个 IP 在 24 小时内尽量不要超过 1,000 页(Craigslist 的 TOS 在此阈值以上会按每页 计算)
- ✅ 保持未登录状态——不要为了抓取而注册 Craigslist 账号
- ✅ 在被明确封禁后,不要再用代理绕过 IP 限制(这正是 3Taps 栽跟头的原因)
- ✅ 请求之间加延迟——至少 2–5 秒
- ✅ 不要抓取个人联系方式用于垃圾营销
- ✅ 不要把原始 Craigslist 数据重新分发,或者包装成你自己的平台内容
- ✅ 将数据用于合法研究、分析或个人用途
- ✅ 在可行时优先使用已公开的 sitemap,而不是暴力爬取
- ✅ 如果要存储数据,入库时就去除 PII(邮箱、电话)
如果你想了解更完整的内容,我们还写过一篇关于 的深度指南。
Python vs. 无代码:哪种方式更适合你?
| 因素 | Python(requests + BS4) | Thunderbit(无代码) |
|---|---|---|
| 搭建时间 | 30–60 分钟(安装、写代码) | 2 分钟(安装 Chrome 扩展) |
| 所需技术能力 | 中级 Python | 无需技术背景 |
| 自定义程度 | 对逻辑、字段、流程完全可控 | AI 自动识别字段,用户可调整 |
| 规模扩展 | 理论上无限(依赖代理与调度) | 适合用 Scheduled Scraper 做周期任务 |
| 防封处理 | 手动处理(请求头、延迟、代理、TLS) | 内置处理(Cloud Scraping) |
| 导出选项 | CSV、JSON(自己写代码) | 免费导出到 Google Sheets、Excel、Airtable、Notion |
| 最适合的人群 | 开发者、数据科学家、自定义数据管道 | 销售团队、房产经纪人、运营经理 |
如果你需要完全自定义,或者准备把它接入更大的数据管道,又或者你想清楚知道底层究竟发生了什么,那就用 Python。若你只想快速拿到结果,不想写或维护代码,那就用 。两者都没问题,关键看你的使用场景,以及你更愿意把时间花在终端还是浏览器里。
结语
Craigslist 是一个丰富且持续更新的数据源,涵盖房源、汽车、招聘、服务、零工等多个类别——而且由于没有公开 API,抓取是规模化获取结构化数据的唯一方法。2025 年真正可行的方案是:从搜索结果里提取嵌入的 JSON-LD(而不是脆弱的 CSS 选择器),使用 requests + BeautifulSoup(而不是 Selenium),加入带有 Sec-Fetch-* 字段的真实请求头,随机化延迟,如果要抓几百页以上,就使用住宅代理。
JSON-LD 方法是对过时教程最大的升级。它更快、更能抵抗页面布局变化,而且完全不需要 JavaScript 渲染。把它和上面的防封策略结合起来,你就能避开大多数爬虫都会撞上的 403 问题。
如果你想完全跳过编码, 可以在几次点击内抓取任意 Craigslist 分类,并直接导出到你喜欢的表格或数据库中。如果你想继续深入,我们关于 和 的指南会更系统地讲解基础内容。
常见问题
抓取 Craigslist 合法吗?
Craigslist 的服务条款禁止自动化抓取,并包含约定损害赔偿条款(每天超过 1,000 页后,每页 $0.25)。不过,近期法院判决——尤其是 Meta v. Bright Data(2024)和 hiQ v. LinkedIn(2022)——已经缩小了对公开可访问数据进行已登出抓取的 CFAA 风险。州法上的侵权主张(如动产侵占)仍然存在风险,尤其是在商业化再分发的场景下。请遵守 robots.txt、保持未登录、加入延迟,并且不要重新分发原始数据。以上仅为一般信息,不构成法律建议。
Craigslist 有公开 API 吗?
没有。Craigslist 只为经过批准的付费发布者提供一个只能写入的 Bulk Posting Interface(BAPI)。它没有公开读取 API,没有开发者门户,也没有专门用于数据获取的限流套餐。你在第三方平台看到的任何“Craigslist API”产品,实际上都是非官方爬虫。
为什么我的 Craigslist 爬虫总是坏掉?
几乎总是因为 HTML 结构变化。Craigslist 在 2023–2024 年重写了搜索结果标记,使用 .result-row 或 .result-info 这类旧选择器的教程已经失效。改用嵌入式 JSON-LD 方法(解析 script#ld_searchpage_results)会稳得多。同时检查你的请求头是否包含 Sec-Fetch-* 字段——缺少这些字段会立刻被封。
不用 Python 也能抓取 Craigslist 吗?
可以。Thunderbit 的 AI 网页爬虫 Chrome 扩展适用于任何 Craigslist 页面——公寓、汽车、招聘、服务都行。点击 “AI Suggest Fields” 自动识别列,点击 “Scrape” 提取数据,然后免费导出到 Google Sheets、Excel、Airtable 或 Notion。无需编程、无需配置、无需管理代理。
多久抓一次 Craigslist 才不容易被封?
如果使用单个住宅 IP,并在页面之间加入随机 2–5 秒延迟,比较可持续的速度大约是每秒 0.3–0.5 个请求。每个 IP 在 24 小时内尽量不要超过 1,000 页,这样可以同时避免封禁和 Craigslist TOS 中的约定损害赔偿阈值。如果在低峰时段(目标城市当地时间凌晨 2–6 点)抓取,封禁率大约可降低 30–40%。如果数据量更大,建议每 20–30 次请求轮换一次住宅代理。
了解更多
