核心要点:
- AI 数据抓取借助大语言模型阅读页面内容,并根据语义识别目标元素。
- 在我们的测试中,将 HTML 转换为 Markdown 可显著减少 AI 消耗的 Token 数量。
- 使用 AI 模型进行数据抓取无法避免触发封锁,因此仍需要代理、延迟与重试机制。
无论是数据抓取还是其他任务,使用 AI 的主要吸引力在于您只需用简单的语言描述需求即可。虽然大语言模型(LLM)承担了大部分解析代码的工作,但 Python 仍是适合的选择,因为其生态系统覆盖了从页面获取到结果验证的每一个环节。
几乎每种 AI 数据抓取工具都有对应的 Python 库可用,但选择时需要有策略。了解这些库,以及 AI 抓取与传统数据采集方式的区别,对于构建真正能提取数据的 AI 抓取程序至关重要。
什么是 AI 数据抓取?
AI 数据抓取是一种数据提取方法,通过 OpenAI 的 GPT 系列模型或 Anthropic 的 Claude 等 LLM 阅读页面内容,再由模型返回符合您预设结构(如 JSON)的数据,帮助您完成提取。
传统数据抓取工具依据元素在 HTML 中的位置定位目标内容,而 AI 数据抓取则通过阅读页面内容来查找目标。因此,数据不仅被识别,还会被同步理解,一条提示词便可用于提取不同页面布局中的数据。
Python 生态系统集成了用于获取页面的库(requests、Playwright)、解析工具(BeautifulSoup)、LLM SDK 以及验证工具(Pydantic)。因此,学习 Python 数据抓取是很好的起点,而结合 AI 智能体等最新技术,其潜力还将进一步提升。
Python 中的 AI 数据抓取与传统数据抓取对比
无论是传统数据抓取还是 AI 数据抓取,都会使用 Requests 库或 Playwright、Selenium 等无头浏览器下载页面,二者的区别在于数据提取方式。
搭建耗时
每个网站需数小时
分钟级
页面布局变化时的维护成本
选择器易失效
通常仍可正常运行,但提示词与代码可能需要调整
单页成本
成本更低
因 Token 消耗而成本更高
速度
毫秒级
每次调用需数秒
输出一致性
每次结果一致
每次执行结果可能不同(具有概率性)
JavaScript 渲染
需要 Playwright 等渲染工具
需要 Playwright 等渲染工具
反机器人机制应对
无法解决该问题
无法解决该问题
所需技能
HTML、CSS 选择器、XPath
HTML 基础、提示词、数据结构
无论是传统数据抓取还是 AI 数据抓取,都会使用 Requests 库或 Playwright、Selenium 等无头浏览器下载页面,二者的区别在于数据提取方式。当不同网站的页面布局差异较大、频繁变化,或涉及评论、列表等跨多个域名的非结构化网页数据时,AI 数据抓取能带来更明显的优势;而在对单一稳定网站进行大批量抓取、需要每次输出保持一致,或预算有限的情况下,传统方法仍更适用。
Python 中 AI 数据抓取的工作原理
AI 数据抓取通常分为五个阶段,整体流程与传统数据提取类似,区别在于用 LLM 能力取代了 CSS 选择器。
- 获取页面。Requests 用于下载静态 HTML,Playwright 则用于渲染通过 JavaScript 加载内容的页面。
- 清理内容。移除脚本、样式、导航栏与页脚,再将剩余内容转换为 Markdown。此转换有助于提升数据提取的准确性,并节省 AI Token 用量。
- 提取数据。将 Markdown 内容与预设结构一同发送给 LLM,由模型填充各字段。
- 验证结果。Pydantic 负责检查字段类型与必填项,避免输出无效数据。
- 存储结果。将结果保存为 JSON、CSV 文件或存入数据库。
适合 AI 数据抓取的 Python 库
在选择 AI 数据抓取工具之前,需先决定是使用现成的库,还是基于 LLM SDK 自行搭建抓取程序。
ScrapeGraphAI
开源(付费 API 另计)
托管与本地均支持
支持
基于提示词的抓取
Crawl4AI
开源
托管与本地均支持
支持
适配 LLM 的 Markdown 输出
Firecrawl
托管 API(开源,可自行部署)
仅托管
支持
无需运行浏览器
Browser Use
开源(可选云端服务)
托管与本地均支持
支持
登录与表单处理
LLM SDK + Pydantic
开源 SDK
任意 API
需配合 Playwright
完全可控
Firecrawl(Python SDK)
Firecrawl 是一种能够渲染 JavaScript、并将页面以 Markdown 或结构化 JSON 形式返回的 API。相较于其他方案,它提供每月 1000 点免费额度,足以体验 AI 数据抓取,甚至完成一个小型项目。
ScrapeGraphAI
开源库 scrapegraphai 以图结构构建抓取流程:SmartScraperGraph 可通过一条提示词从单个页面提取数据,SmartScraperMultiGraph 则将同一提示词应用于多个页面,而 SearchGraph 用于抓取搜索结果中排名靠前的内容。该库支持 OpenAI、Gemini、Groq,以及通过 Ollama 调用的本地模型。
Crawl4AI
Crawl4AI 是一种专为 LLM 与 AI 应用设计的开源异步爬虫,使用 Playwright 渲染页面并输出整洁的 Markdown。其 LLMExtractionStrategy 接收 Pydantic 数据结构用于提取数据,并返回 JSON。
Browser Use
Browser Use 运行 AI 智能体,驱动真实浏览器完成登录、表单填写、点击“加载更多”按钮等多步骤任务。由于每一步都需要调用一次 LLM,因此速度更慢、成本更高,但能够完成复杂任务。
自行搭建:LLM SDK 加上 Pydantic
最精简的方案是使用 OpenAI 或 Anthropic 的 SDK 并启用结构化输出:传入一个 Pydantic 模型,API 便会返回与该模型字段及类型完全匹配的 JSON。这种方式可带来完全的控制权,但需要自行编写页面获取、清理与代理相关的代码。
如何用 Python 构建 AI 数据抓取程序(分步教程)
本文将采用结合 Pydantic 的自行搭建方式,因为 ScrapeGraphAI、Crawl4AI 等库在后台执行的也是相同的获取、清理与提取步骤。如果您刚接触 AI 数据抓取,建议至少亲手搭建一次,以了解每项工具设置的具体作用。
本文将抓取 Books to Scrape 网站的数据,这是一个专为练习数据抓取搭建的站点。开始前,请安装 Python 3.10 或更高版本,我们在 Python 3.14.4 上测试了该脚本。本文使用 Claude Opus 5.5(claude-opus-5-5),但使用 OpenAI 等其他厂商的模型流程也类似。
第一步:搭建开发环境
以下代码将创建虚拟环境、安装所需的全部库,并配置浏览器。请在 PowerShell 中依次执行以下命令:
mkdir ai-scraper
cd ai-scraper
python -m venv venv
venv\Scripts\activate
pip install requests playwright beautifulsoup4 markdownify anthropic pydantic
playwright install chromium
$env:ANTHROPIC_API_KEY="your-key"
请注意,“your-key”只是占位符。将其设置为环境变量,可避免将密钥直接写入 Python 脚本中。
在 macOS 或 Linux 上,使用 source venv/bin/activate 激活环境,并通过 export ANTHROPIC_API_KEY="your-key" 设置密钥。如需通过代理路由请求,可用相同方式设置 PROXY_URL,格式为 http://user:pass@host:port。
第二步:获取页面
Books to Scrape 是一个布局简单的静态网站,使用 Requests 库配合代理即可完成获取。
html = requests.get(url, proxies=PROXIES, timeout=30).text
对于通过 JavaScript 渲染的页面,则需要使用 Playwright,并等待网络请求进入空闲状态:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch(proxy={"server": "http://HOST:PORT", "username": "USER", "password": "PASS"})
page = browser.new_page()
page.goto(url, wait_until="networkidle")
html = page.content()
browser.close()
第三步:清理 HTML 并转换为 Markdown
移除不含数据的标签,仅保留商品列表。由于评分信息存放在 Markdown 会丢弃的 CSS 类中,因此需要将其复制为文本内容。
def clean(html):
soup = BeautifulSoup(html, "html.parser")
for tag in soup(["script", "style", "nav", "footer", "img", "form"]):
tag.decompose()
for p in soup.select("p.star-rating"):
p.string = "Rating: " + p["class"][1]
main = soup.select_one("ol.row") or soup.body
return md(str(main))
Claude 按 Token 数量计费,因此清理步骤有助于降低成本。在我们的测试中,第一页的原始 HTML 包含 15350 个 Token,转换为 Markdown 后缩减至 1663 个。
第四步:用 Pydantic 定义输出结构
Pydantic 库可帮助我们准确告知 Claude 需要返回的内容,只需编写一个 Python 类,每个字段及其类型各占一行即可。每本书需要四个字段:title(文本)、price(数字)、availability(文本)与 rating(整数)。除 title 外,其余字段均可缺失。
class Book(BaseModel):
title: str
price: float | None
availability: str | None
rating: int | None
第五步:用 LLM 提取结构化数据
该代码向 Claude 发送一个包含三部分内容的请求:清理后的 Markdown、BookList 数据结构,以及系统提示词。Claude 读取 Markdown 内容,识别每本书,并填充相应字段。结构化输出会强制返回与预设结构匹配的 JSON。
系统提示词是随每次数据提取请求发送的固定指令。我们的提示词要求 Claude 在页面未显示某字段时返回 null(空值),而非自行猜测。
resp = client.messages.parse(
model=MODEL, max_tokens=16000, system=SYSTEM,
messages=[{"role": "user", "content": markdown}],
output_format=BookList)
参数 max_tokens 用于限制回复长度,从而约束 Claude 的思考过程。完整代码中的 extract() 函数负责从回复中提取出 JSON 内容。
第六步:验证并保存结果
通过 BookList.model_validate_json(),可读取第五步生成的 JSON 并对照预设结构进行校验;若字段缺失或类型错误,Pydantic 将抛出ValidationError,脚本会记录该页面后继续执行。
try:
books += BookList.model_validate_json(extract(markdown)).books
except ValidationError as e:
print("Invalid output, page skipped:", e)
随后,save() 函数会将每本验证通过的图书写入 books.json 与 books.csv:
def save(books):
rows = [b.model_dump() for b in books]
with open("books.json", "w") as f:
json.dump(rows, f, indent=2)
with open("books.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=list(Book.model_fields))
writer.writeheader()
writer.writerows(rows)
完整代码
将以下代码保存为项目(ai-scraper)文件夹中的 scraper.py。
import csv, json, os, time
from urllib.parse import urljoin
import requests
from anthropic import Anthropic
from bs4 import BeautifulSoup
from markdownify import markdownify as md
from pydantic import BaseModel, ValidationError
START_URL = "https://books.toscrape.com/"
MODEL = "claude-opus-5-5"
PROXY = os.getenv("PROXY_URL") # http://user:pass@host:port
PROXIES = {"http": PROXY, "https": PROXY} if PROXY else None
SYSTEM = ("Extract every book. Use the link title as the full title. "
"Rating is 1-5. Return null for missing values. Never guess.")
client = Anthropic() # reads ANTHROPIC_API_KEY
class Book(BaseModel):
title: str
price: float | None
availability: str | None
rating: int | None
class BookList(BaseModel):
books: list[Book]
def fetch(url):
r = requests.get(url, proxies=PROXIES, timeout=30)
r.raise_for_status()
return r.text
def clean(html):
soup = BeautifulSoup(html, "html.parser")
for tag in soup(["script", "style", "nav", "footer", "img", "form"]):
tag.decompose()
for p in soup.select("p.star-rating"):
p.string = "Rating: " + p["class"][1]
main = soup.select_one("ol.row") or soup.body
return md(str(main))
def tokens(text):
return client.messages.count_tokens(
model=MODEL, messages=[{"role": "user", "content": text}]
).input_tokens
def extract(markdown):
resp = client.messages.parse(
model=MODEL,
max_tokens=16000,
system=SYSTEM,
messages=[{"role": "user", "content": markdown}],
output_format=BookList,
)
return next(b.text for b in resp.content if b.type == "text")
def next_url(html, url):
link = BeautifulSoup(html, "html.parser").select_one("li.next a")
return urljoin(url, link["href"]) if link else None
def save(books):
rows = [b.model_dump() for b in books]
with open("books.json", "w") as f:
json.dump(rows, f, indent=2)
with open("books.csv", "w", newline="") as f:
writer = csv.DictWriter(f, fieldnames=list(Book.model_fields))
writer.writeheader()
writer.writerows(rows)
def main(max_pages=3):
url, books = START_URL, []
for _ in range(max_pages):
html = fetch(url)
markdown = clean(html)
print(f"{tokens(html)} -> {tokens(markdown)} tokens")
try:
books += BookList.model_validate_json(extract(markdown)).books
except ValidationError as e:
print("Invalid output, page skipped:", e)
url = next_url(html, url)
if not url:
break
time.sleep(1)
save(books)
print(f"Saved {len(books)} books to books.json and books.csv")
if __name__ == "__main__":
main()
在虚拟环境已激活、ANTHROPIC_API_KEY 已设置的状态下,于 PowerShell 中执行以下命令运行代码:
python scraper.py
若设置无误,项目文件夹中将生成 books.json 与 books.csv 文件,其中包含从 Books to Scrape 提取的所需数据,输出效果大致如下:
[
{
"title": "A Light in the Attic",
"price": 51.77,
"availability": "In stock",
"rating": 3
},
{
"title": "Tipping the Velvet",
"price": 53.74,
"availability": "In stock",
"rating": 1
}
]
AI 抓取的规模化扩展
我们的 Python 脚本仅按顺序处理三个页面,适合小规模低频测试。若实际场景涉及数千个页面,可考虑以下三种策略,实现 AI 数据抓取项目的规模化。
- 批量处理。使用 asyncio 并行处理多个页面,并通过 semaphore 限制并发数量,既能保护目标网站,也能使请求保持在 LLM 速率限制之内。
- 分页处理。用普通代码跟踪“下一页”链接,如 next_url() 的实现方式,这比消耗 Token 更经济、更可靠。
- 动态内容。处理无限滚动和“加载更多”,可使用 Playwright 的操作,如 page.mouse.wheel() 或 page.click() 来实现。如流程需要登录,可使用 Browser Use。
如何在使用 AI 进行数据抓取时避免被封锁
使用 AI 抓取网站改变的是数据解析方式,而不是请求在目标网站眼中的样子。速率限制、IP 封禁和 CAPTCHA 依然存在,就像其他数据抓取工具一样。要成功完成抓取,这里同样适用一些基本的最佳做法。
使用 AI 时,常规的数据抓取规则同样适用:遵守 robots.txt、避免涉及个人数据或受版权保护的内容、并实现指数退避。当网站返回 429(请求过多) 或 403(禁止访问) 等错误时,别忘了限制请求频率。即便采取了这些措施,仍然需要使用代理。
轮换住宅代理会通过真实家庭设备的 IP 地址发送请求,并可为每个请求分配一个新 IP。在目标网站看来,您的爬虫就像是许多普通访客,而不是单一的抓取程序。
借助 MarsProxies 住宅代理,您可获得覆盖 190 多个国家和地区、超过 100 万个 IP 的代理池。将其接入 AI 网络爬取流程非常简单:只需将 MarsProxies 的端点和凭证设置为 PROXY_URL,脚本就会让每个请求都通过这些代理路由。
除了优质代理外,发送真实浏览器的 User-Agent 请求头也很重要,因为 Requests 默认的 User-Agent 会将您的爬虫标识为 Python 脚本。
2026年用 Python AI 爬虫稳定抓取数据不被封
获取住宅代理Python AI 网络爬取推荐做法
在 AI 驱动的网络爬取中,让 LLM 专注于它最擅长的工作,其余任务交给代码处理,效果更佳。基本原则是:用 LLM 来理解语义,用代码处理抓取、清洗、分页和校验。
- 降低 token 成本:仅发送主容器中清洗后的 Markdown 内容,并缓存已处理的页面。
- 避免生成虚假数据:使用严格的 schema,并通过提示词让模型在不确定时返回 null 而非猜测,再对照实际页面进行抽查。
- 用 AI 编写选择器,再按传统方式抓取:针对结构稳定的网站,只需让 LLM 生成一次 CSS 选择器,然后用 BeautifulSoup 执行。
- 处理错误和重试:采用退避策略重试,跳过无效页面,并记录提示词和输出结果以便复现。
- 选择合适的模型:对于简单的列表页,可先使用 Claude Haiku 4.5 等较小的模型,仅在准确率下降时再换用更大的模型。
- 负责任地抓取:遵守 robots.txt 和网站条款,保持较低的请求频率,并避免涉及个人数据。
AI 网络爬取的实际使用场景
有许多方式可以借助数据抓取赚钱,或将其应用于专业领域,以下是客户中较为常见的一些数据抓取项目。
- 价格监控:从不同页面布局的商店中提取价格数据。
- 潜在客户名单:从目录中提取公司名称、联系方式等数据。
- 评论与情感提取:在同一次调用中抓取评论并标注情感倾向。
- 新闻监控:从多家媒体收集标题和摘要。
- RAG 流程:将清洗后的网络数据输入检索增强生成(RAG)系统和 AI 智能体。
结语
一个基础的 AI 网络爬取 Python 工作流大致如下:用 Requests 或 Playwright 获取页面,清洗为 Markdown,用 LLM 提取数据,再用 Pydantic 进行校验。加入轮换住宅代理后,同一个脚本就能从数千个页面采集网络数据。
常见问题
可以用 AI 抓取网站吗?
可以。大多数 AI 模型都适用于布局各异的网站抓取。您仍然需要代码来获取页面,但 LLM 可以简化解析过程:即使各网站的 HTML 结构不同,它也能理解内容并返回您所需要的字段。
哪种 LLM 更适合用于网络爬取?
我们测试过 Claude Opus 5.5。对于简单的列表页,可以尝试 Claude Haiku 4.5 等成本更低的模型并对比效果。OpenAI 等厂商推出的最新模型同样可能表现良好。
AI 数据抓取合法吗?
在许多国家和地区,抓取公开数据是合法的,但个人数据、版权和网站条款的适用情况会因使用场景而异。使用 AI 并不会改变数据抓取的合法性:传统爬虫不能抓取的数据,AI 爬虫同样不能抓取。
AI 网络爬取需要使用代理吗?
需要,除非您只是在做测试。网站会根据 IP 和请求频率屏蔽爬虫,使用轮换代理可以分散请求来源。任何规模较大的项目如果不使用代理,都会遇到 IP 封禁和 CAPTCHA,或者因为速率限制而耗费大量时间。
AI 网络爬取每页的成本是多少?
本文的示例脚本大约使用了 1700 个输入 token。按 Claude Opus 5.5 的价格计算,加上输出和思考过程的 token,每页成本约为 0.03 美元。页面越长、模型越大,成本就越高,因此清洗 HTML 并选用更小的模型可以降低费用。
AI 网络爬取能处理依赖 JavaScript 的网站吗?
可以,但需要先用 Playwright 或 Firecrawl 等数据抓取工具渲染页面,再从渲染后的 HTML 中提取数据。LLM 只能读取接收到的 HTML,如果不进行渲染,就会遗漏通过 JavaScript 加载的内容。