我如何用 Python 抓取 Craigslist(且不被封禁)

最后更新于 April 16, 2026
我如何用 Python 抓取 Craigslist(且不被封禁)

Craigslist 目前在约 700 个本地站点上每月仍能带来大约 1.08 亿次访问——但它依然没有公开 API。如果你想从那些公寓房源、二手车、招聘信息或零工广告里拿到结构化数据,抓取几乎就是唯一选择。

不过,Craigslist 自家的反爬系统非常严格。它不用 Cloudflare,也不用 DataDome,而是采用了自己基于 nginx 的限流机制,而且已经打磨了十多年。只要请求方式不对,你第二杯咖啡还没喝完,可能就已经收到一个干脆利落的 403。我花了大量时间测试 Craigslist 的各种防护策略,这篇指南就是这些经验的总结:一份适用于 2025 年、覆盖所有分类的 Python 教程,内容包括 JSON-LD 抽取方法(相比过时教程,这是最大的提升)、真实有效的防封策略、法律风险分析,以及一个无需写代码的替代方案,适合只想拿到数据、不想动手写一行代码的人。

用 Python 抓取 Craigslist 到底是什么意思?

用 Python 抓取 Craigslist,指的是通过脚本程序化访问 Craigslist 页面,提取你关心的结构化数据——比如标题、价格、描述、图片、位置、发布时间——并把它保存到表格、数据库或 JSON 文件中。

Python 之所以是首选语言,是因为它的库生态非常成熟。借助 requestsBeautifulSouplxmlcurl_cffi,你可以在 100 行以内写出一个可用的 Craigslist 爬虫。社区也非常庞大,所以当 Craigslist 发生变化时(它确实会变),通常早就有人把解决方案找出来了。

最关键的一点是:Craigslist 并没有公开的读取 API。它唯一正式提供的程序化接口是 Bulk Posting Interface(BAPI),而且它只是写入接口——只允许经过批准的付费发布者提交信息,不能用来读取数据。你在第三方平台上看到的任何“Craigslist API”产品,本质上都是非官方爬虫,而不是 Craigslist 授权的接口。如果你需要批量数据,就只能自己抓取。

为什么要抓取 Craigslist?真实应用场景有哪些?

Craigslist 不只是一个买二手沙发的平台。它其实是一个覆盖多个垂直领域、持续更新的大型数据源。下面这些人最能从中受益:

应用场景受益人群提取内容
公寓与租金监测房产经纪人、租客、PropTech 公司价格、面积、卧室数、街区、经纬度
二手车市场分析车商、消费者应用、研究人员价格、品牌、车型、年份、里程、车况
招聘市场研究招聘人员、劳动经济学者、劳动力分析师职位标题、薪资、雇佣类型、发布时间
线索开发销售团队、服务商联系方式、公司名称、服务区域
竞争定价分析本地服务商、电商运营团队服务价格、描述、覆盖区域

最常被引用的学术案例之一是 Kaggle 的“Used Cars Dataset”——大约 50 万条美国二手车信息,包含 26 个变量,已经成为几十篇论文的基础,其中包括一篇 2024 年在 ResearchGate 上发布的美国二手车市场动态研究。对冲基金也曾购买聚合后的 Craigslist 租金数据,用于研究租金趋势。销售团队则经常抓取服务和零工分类,用来获取潜在客户。

数学很简单:手工复制粘贴 8 小时 vs. 一个设计良好的爬虫大约 10 分钟。

craigslist_stats_55285c3a34.png

用 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 + BeautifulSoupSeleniumPlaywright
速度每秒 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 挑战。所有仍在维护的 GitHub Craigslist 爬虫 都使用 requests + BeautifulSoup 或 Scrapy,几乎没有项目会用 Selenium 或 Playwright。这个选择不是巧合——浏览器自动化框架会额外吃掉几百 MB 内存、速度慢 10–100 倍,而且还会带来更明显的指纹,而这些代价换来的收益并不大。

我的建议:

  • requests + BS4:从这里开始。它和 JSON-LD 抽取方法天然契合,足以覆盖 95% 的 Craigslist 抓取需求。
  • Selenium:只有当你必须与某些详情页上的动态内容交互时才用(在 Craigslist 上这种情况很少见)。
  • Playwright:如果你要用异步并发扩展到成千上万的页面,可以考虑它——但说实话,Craigslist 的瓶颈是限流,不是你库的吞吐能力。

如果你想看更完整的比较,我们另外写过 Playwright vs. Puppeteer 以及 最佳 Python 网页爬虫工具 的专题文章。

无需写 Python 也能抓取 Craigslist Get Started Free

无代码替代方案:不写 Python 也能抓取 Craigslist

在开始写代码前先插一句——这一部分是给不写程序的人看的。房产经纪人、销售团队、运营经理都适用:如果你只是想要数据,而不想写 Python,那有更快的路径。

Thunderbit 是一款以 Chrome 扩展形式运行的 AI 网页爬虫,只需要大约 2 次点击,就能抓取 Craigslist,而且完全不需要代码。流程如下:

  1. 打开任意 Craigslist 搜索结果页(公寓、汽车、招聘等任意分类都可以)。
  2. 在 Thunderbit 侧边栏点击 “AI Suggest Fields”。AI 会读取页面,并自动识别标题、价格、位置、链接等列。
  3. 点击 “Scrape”——几秒钟内就会完成数据提取。
  4. 使用 Subpage Scraping 逐个访问列表详情页,补充完整描述、电话号码、图片和属性信息。
  5. 直接导出到 Google Sheets、Excel、Airtable 或 Notion,完全免费。

如果你有周期性需求——比如每天监控房租价格,或者每周抓一份招聘信息快照——Thunderbit 的 Scheduled Scraper 允许你用自然语言描述计划,系统会自动运行。无需 cron 任务,也不用搭服务器。

Thunderbit 还通过 Cloud Scraping 模式自动处理反爬机制,所以你不必操心轮换代理或编写复杂请求头。如果你想试试,可以安装 Thunderbit Chrome Extension 亲自体验一下。

如果你想要完全的控制权和自定义能力,那就继续往下看 Python 的详细步骤吧。

逐步教程:如何用 Python 抓取 Craigslist(完整指南)

  • 难度: 中级
  • 所需时间: 约 30 分钟(配置 + 首次抓取)
  • 你需要准备: Python 3.8+、Chrome 浏览器(用于检查页面)、终端

第 1 步:搭建 Python 环境

安装所需库:

pip install requests beautifulsoup4 lxml

lxml 不是必须的,但它能明显加快 BeautifulSoup 的解析速度。如果后面遇到 TLS 指纹识别问题(后面的防封章节会讲),你也可以安装 curl_cffi

pip install curl_cffi

你的导入代码如下:

import requests
from bs4 import BeautifulSoup
import json
import csv
import time
import random

现在你应该已经有了一个干净的 Python 环境,所有依赖也都安装完毕。

第 2 步:为任意分类构建 Craigslist URL

使用城市 + 分类 slug + 可选筛选条件,动态生成目标链接:

from urllib.parse import urlencode

BASE = "https://{city}.craigslist.org/search/{slug}"

def build_url(city, slug, **params):
    return f"{BASE.format(city=city, slug=slug)}?{urlencode(params)}"

# 示例:纽约公寓,价格 1500–3000 美元,带图片
url = build_url("newyork", "apa", min_price=1500, max_price=3000, hasPic=1)
print(url)
# 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 区块:

HEADERS = {
    "User-Agent": (
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
        "AppleWebKit/537.36 (KHTML, like Gecko) "
        "Chrome/124.0.0.0 Safari/537.36"
    ),
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
    "Accept-Language": "en-US,en;q=0.9",
    "Accept-Encoding": "gzip, deflate, br",
    "Referer": "https://www.craigslist.org/",
    "Sec-Fetch-Dest": "document",
    "Sec-Fetch-Mode": "navigate",
    "Sec-Fetch-Site": "same-origin",
    "Upgrade-Insecure-Requests": "1",
}

session = requests.Session()
r = session.get(url, headers=HEADERS, timeout=20)
r.raise_for_status()

soup = BeautifulSoup(r.text, "html.parser")
tag = soup.select_one("script#ld_searchpage_results")
data = json.loads(tag.text) if tag else {"itemListElement": []}

如果 tagNone,说明该分类没有 JSON-LD 区块——那就回退到 HTML 解析(见上面的选择器表)。对于公寓、汽车和出售物品分类,JSON-LD 区块通常都很稳定。

第 4 步:把列表数据解析成结构化记录

遍历 JSON 项,提取你需要的字段:

listings = []
for entry in data["itemListElement"]:
    item = entry["item"]
    offers = item.get("offers", {}) or {}
    addr = (offers.get("availableAtOrFrom") or {}).get("address", {})
    listings.append({
        "name":     item.get("name"),
        "url":      offers.get("url"),
        "price":    offers.get("price"),
        "currency": offers.get("priceCurrency"),
        "locality": addr.get("addressLocality"),
        "region":   addr.get("addressRegion"),
        "image":    item.get("image"),
    })

print(f"Found {len(listings)} listings")

你应该会看到类似“Found 120 listings”的输出(Craigslist 每页显示 120 条结果)。有些帖子如果发布者没有填写价格,price 可能会是 None——在后续逻辑里记得妥善处理。

第 5 步:抓取详情页,获取更丰富的数据

搜索结果页只能给你摘要信息。如果你想要完整描述、属性信息(卧室数、面积、宠物政策)、经纬度坐标和图片,就需要访问每条信息对应的详情页。

def fetch_detail(url, session):
    r = session.get(url, headers=HEADERS, timeout=20)
    r.raise_for_status()
    s = BeautifulSoup(r.text, "html.parser")
    body = s.select_one("#postingbody")
    mp = s.select_one("#map")
    return {
        "description": body.get_text("\n", strip=True) if body else None,
        "attributes":  [x.get_text(" ", strip=True) 
                        for x in s.select("p.attrgroup span, div.attrgroup .attr")],
        "lat": mp.get("data-latitude") if mp else None,
        "lng": mp.get("data-longitude") if mp else None,
        "images": [img["src"] for img in s.select("div.gallery img")],
    }

for item in listings:
    item.update(fetch_detail(item["url"], session))
    time.sleep(random.uniform(3, 6))  # 关键:加入随机抖动,避免封禁

time.sleep(random.uniform(3, 6)) 这一步不是可选项。跳过它,你可能在几十次请求内就被 403。详情页是服务端渲染的,选择器也很稳定(#titletextonly#postingbody#map 这些自大约 2017 年起就没怎么变过)——这大概是 Craigslist 为数不多真正稳定的地方之一。

第 6 步:处理分页,抓取全部结果

Craigslist 使用 ?s=120 偏移参数来分页。每页显示 120 条结果,最大偏移量通常是 2999。

def iter_all(city, slug, max_pages=25, **filters):
    for page in range(max_pages):
        offset = page * 120
        url = build_url(city, slug, s=offset, **filters)
        r = session.get(url, headers=HEADERS, timeout=20)
        r.raise_for_status()
        soup = BeautifulSoup(r.text, "html.parser")
        tag = soup.select_one("script#ld_searchpage_results")
        if not tag:
            break
        data = json.loads(tag.text)
        items = data.get("itemListElement", [])
        if not items:
            break
        for entry in items:
            item = entry["item"]
            offers = item.get("offers", {}) or {}
            yield {
                "name": item.get("name"),
                "url": offers.get("url"),
                "price": offers.get("price"),
            }
        time.sleep(random.uniform(2.5, 5.0))

不要试图在短时间内连续抓取成千上万页。Craigslist 的限流是按 IP 计算的,而无论你用什么库,单个 IP 的可持续吞吐量都大概只有每秒 0.3–0.5 个请求。这个上限是 Craigslist 设定的,不是 Python 的问题。

第 7 步:把 Craigslist 数据导出为 CSV、JSON 或 Google Sheets

保存你的结果:

# CSV
with open("craigslist.csv", "w", newline="", encoding="utf-8") as f:
    w = csv.DictWriter(f, fieldnames=listings[0].keys())
    w.writeheader()
    w.writerows(listings)

# JSON
with open("craigslist.json", "w", encoding="utf-8") as f:
    json.dump(listings, f, indent=2, ensure_ascii=False)

如果你想彻底跳过导出代码,Thunderbit 可以直接从浏览器免费导出到 Google Sheets、Excel、Airtable 或 Notion。对于 Python 工作流来说,CSV 和 JSON 仍然是标准输出格式。你也可以把数据直接送入 pandas 做分析,或者用 sqlite3 存进数据库。

用 Python 抓取 Craigslist 时,如何避免被封禁

很多教程都会把这一部分轻描淡写地带过。但 Craigslist 的反爬系统是自研的,不是现成方案,而且有一些很特别的细节。

craigslist_antibot_ae9ddc3f54.png

使用真实、完整的请求头

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,再等待。

from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

retry = Retry(
    total=5,
    backoff_factor=1.5,  # 1.5, 3, 6, 12, 24 秒
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods={"GET"},
    respect_retry_after_header=True,
)
adapter = HTTPAdapter(max_retries=retry)
session.mount("https://", adapter)

再补充一个技巧:社区反馈一直显示,目标城市当地时间凌晨 2–6 点是最安全的抓取窗口,封禁率比白天低大约 30–40%。

TLS 指纹识别——最隐蔽的陷阱

Craigslist 的机器人检测层会检查 TLS ClientHello。Python 的 requests 库(基于 OpenSSL)所产生的 JA3 指纹,并不对应任何真实浏览器。即便你的 User-Agent 完美无误,只要 TLS 指纹不是浏览器级别,依然会被识别为异常。解决方法是使用 curl_cffi 并设置 impersonate="chrome124",让它模拟 Chrome 的 TLS 握手:

from curl_cffi import requests as cffi_requests

r = cffi_requests.get(url, headers=HEADERS, impersonate="chrome124")

如果你在使用干净的住宅 IP、正确请求头的情况下仍然频繁遇到 403,那大概率就是 TLS 指纹惹的祸。

Craigslist robots.txt、服务条款与负责任抓取

大多数教程要么完全不提这一点,要么只在 FAQ 里随便带过一句。考虑到 Craigslist 曾在 2017 年针对 RadPad 的抓取纠纷中拿到 6050 万美元判决,这件事显然不该只当脚注处理。

Craigslist 的 robots.txt 到底写了什么

robots.txt 文件其实非常短。它只有一个 User-agent: * 区块,并且只禁止了 7 个路径:

Disallow: /reply
Disallow: /fb/
Disallow: /suggest
Disallow: /flag
Disallow: /mf
Disallow: /mailflag
Disallow: /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 最终以 100 万美元和解

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 在此阈值以上会按每页 $0.25 的约定损害赔偿 计算)
  • ✅ 保持未登录状态——不要为了抓取而注册 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。若你只想快速拿到结果,不想写或维护代码,那就用 Thunderbit。两者都没问题,关键看你的使用场景,以及你更愿意把时间花在终端还是浏览器里。

结语

Craigslist 是一个丰富且持续更新的数据源,涵盖房源、汽车、招聘、服务、零工等多个类别——而且由于没有公开 API,抓取是规模化获取结构化数据的唯一方法。2025 年真正可行的方案是:从搜索结果里提取嵌入的 JSON-LD(而不是脆弱的 CSS 选择器),使用 requests + BeautifulSoup(而不是 Selenium),加入带有 Sec-Fetch-* 字段的真实请求头,随机化延迟,如果要抓几百页以上,就使用住宅代理。

JSON-LD 方法是对过时教程最大的升级。它更快、更能抵抗页面布局变化,而且完全不需要 JavaScript 渲染。把它和上面的防封策略结合起来,你就能避开大多数爬虫都会撞上的 403 问题。

如果你想完全跳过编码,Thunderbit Chrome Extension 可以在几次点击内抓取任意 Craigslist 分类,并直接导出到你喜欢的表格或数据库中。如果你想继续深入,我们关于 如何用 Python 进行网页抓取网页抓取最佳实践 的指南会更系统地讲解基础内容。

试试 Thunderbit 抓取 Craigslist

试试 AI 网页爬虫抓取 Craigslist 数据 Get Started Free

常见问题

抓取 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 次请求轮换一次住宅代理。

了解更多

Ke
Ke
Thunderbit 首席技术官 | 高级数据科学家与机器学习专家 Ke Shen 拥有近十年的机器学习和数据科学经验,毕业于哥伦比亚大学,曾任 Walmart Labs 高级数据科学家。他在 Python、R、Java 和统计学方面拥有深厚且备受同行认可的专业能力,并分享如何将复杂的 AI 算法从理论落地到生产级架构的实战经验。
目录

只要开口,就能抓取网页

用简单英文说出你的需求。或者更简单,什么都不用说。

试用 Thunderbit 免费
使用 AI 提取数据
轻松将数据传输到 Google Sheets、Airtable 或 Notion
Chrome Store Rating
PRODUCT HUNT#1 Product of the Week