前几天有人问我:“我想抓某个电商网站的商品数据,现在是不是直接用AI工具就行?”我第一反应是别急着回答,得先问清楚他到底要抓多少、页面结构稳不稳定、数据量有多大。因为AI加持下的爬虫工具确实改变了很多玩法,但“直接问AI要数据”和“写一套稳定抓取流程”完全是两码事。
这篇东西是我近期集中做的一组对照测试总结,把现在主流的AI爬虫思路按工具类型、适用场景、成本结构、稳定性挨个过了一遍,也放了可直接参考的代码流程。适合这些读者:接到抓取需求但不确定用什么方案的开发者,想用AI快速拿结构化数据做分析的运营或研究人员,以及想搞清楚“什么场景别盲目上AI”的项目负责人。
先说结论:AI爬虫不是要替代传统抓取,而是把过去必须写大量解析代码的环节,变成用提示词解决。但哪些环节AI真帮得上,哪些环节它完全无能为力,这是选型之前必须先搞清楚的事。
1. 选型前先想明白:AI加持下的抓取链路到底变了什么
1.1 一条完整抓取链路里的三件事
很多人理解爬虫就是“发个请求拿HTML”,这是最大的误解。任何网页抓取流程,拆到最底层永远只有三件事:
- 把目标页面以可解析的形式拿回来
- 从拿回来的HTML或文本里挑出你真正需要的字段
- 把挑出来的字段清洗成规范统一的数据格式
传统方案里,第一件事靠HTTP请求库加代理池,第二件事靠CSS选择器、XPath、正则表达式,第三件事靠写各种字符串处理和校验规则。这三件事各是一摊工程,写起来不复杂,但维护起来很烦。
AI方案介入后,第一件事基本不变——你仍然要解决请求、登录、渲染这些问题。真正的变化发生在第二件事和第三件事上:页面结构不再需要人手写选择器去定位,你只要告诉模型“我要商品名、价格、库存”,它能直接理解语义从HTML里提取;清洗逻辑也可以部分交给提示词,比如统一价格格式、过滤无效记录。
为什么AI能在这两步起作用?因为“从HTML到你想要的字段”这个映射关系,本质上是从非结构化文本里抽取结构化信息,这正是大语言模型最擅长的事情。页面布局再怎么变,只要语义没变,模型就能靠理解力兜住。这是AI爬虫最根本的价值逻辑。
1.2 AI工具动了哪一环,哪些环节AI其实帮不上忙
先说明AI能帮上的强项:
- 页面结构千奇百怪、没有稳定规律时,用自然语言描述字段就能提取
- 站点改版后,选择器大面积失效,AI方案可以免改代码直接适配新结构
- 字段合并、去重、格式归一化这类清洗逻辑,可以用提示词快速完成
- 遇到动态加载但接口抓不到的情况,可以用视觉加交互的方式模拟操作
再说AI帮不上忙的部分:
- IP封禁、登录态保持、验证码、频率限制、渲染等待,这些网络请求层面的问题,AI完全解决不了
- 大规模翻页抓取时,AI方案的空间复杂度会暴涨,因为每页都要消耗计算资源
- 模型可能产生幻觉,返回页面里根本不存在的字段,需要额外兜底校验
我见过一個项目组上了AI方案之后以为万事大吉,结果跑了两小时就被站点封了IP,他们才发现自己连最基本的请求头都没做。这就是没分清“解析层的智能”和“请求层的工程”导致的典型翻车。选型之前把这两件事分开,后面才不会踩大坑。
2. 主流AI爬虫思路盘点与实测对比
2.1 对话问答型:让大模型直接读网页给答案
这种用法最直观,也是很多人对“AI爬虫”的第一印象:复制一段URL或者整页HTML贴进对话窗口,然后问“这个页面里所有商品名称和价格是什么”,模型直接输出结构化列表。
优点非常突出:零代码上手,适合一次性需求。比如你要分析某个文章页面的核心观点,或者从某个活动页提炼几个关键信息点,这类用法几分钟就能出结果。缺点也很明确:第一是token开销大,一页几万个字符的HTML贴进去,几轮对话下来费用不少;第二是输出格式不稳定,今天给你Markdown列表,明天可能给你JSON,后天可能给你一段带解释的文字;第三是它只能“读页面”,不能“操作系统”,你要翻页、点分类筛选、处理弹出登录框,它完全做不了。
我实测这类用法在“读文章正文提炼要点”这种场景下效果很好,但在“抓200个商品列表页”这种规模需求下基本不可用,理由就是上面三条缺点的叠加。如果你只是临时要一份页面摘要,可以选它;如果想建一个能长期跑的任务,尽快换思路。
2.2 结构化提取型:把HTML交给AI转成JSON
这类是我目前实测下来性价比最均衡的一类,也是我建议大多数开发者和数据分析师优先考虑的路线。
核心做法分四步:
- 用传统请求方式把HTML抓下来
- 做预处理:去掉script、style、导航、广告位这些无关区块
- 把裁剪后的正文片段连同“字段说明”一起发给大模型
- 让模型返回JSON,再用一层规则校验兜底
这种方案的好处在于:你保留了对抓取全过程的传统控制——限速、代理、登录态、重试策略都还是自己说了算;同时又享受了AI的解析智能,页面结构随便怎么变,只要字段语义不变,提示词都不用改。
我做过一个对照实验,同一个页面让传统选择器解析和AI解析各跑一遍。传统方案需要花15分钟定位各种选择器表达式,AI方案只花了2分钟写了一段提示词,结果质量基本持平。之后站点改版,传统方案的选择器废了一半,而AI方案完全没受影响。这个对比在我这里基本定调:如果页面结构不够稳定,AI解析型方案的维护成本优势是碾压级的。
2.3 浏览器自动化加AI编排型:复杂交互场景的正解
还有一种场景绕不开:要登录、要滚动加载、要点筛选条件、要等动态渲染。这种站点用纯HTTP请求很难搞定,必须上浏览器自动化工具。AI在这类方案里的角色不是解析HTML,而是当“导航大脑”。
举个例子:页面需要先点开“价格区间”筛选,再滚动到底部触发加载,最后截屏确认结果区域出现。传统做法是写死每一步操作,页面稍微改个按钮位置就崩。AI编排型方案的做法是:把屏幕截图交给视觉模型,让模型判断“当前页面处于什么状态”,再输出“下一步应该做什么动作”,工具执行动作后再次截图循环,直到目标完成。
这类方案灵活度最高,但代价也很明显:速度慢、资源消耗大、token费用可观,而且由于多了一步视觉模型判断,整个链路的稳定性受模型推理结果影响,时好时坏。我在模拟项目里把它用在一个竞品监控场景,每天只跑一次,预算可控,效果还不错。如果要高频执行,建议谨慎评估成本。
2.4 三类思路的对比速查表
| 维度 | 对话问答型 | 结构化提取型 | 浏览器自动化+AI编排型 |
|---|---|---|---|
| 目标用户 | 运营、研究员,非程序员 | 开发者、数据分析师 | 开发者、长期运维团队 |
| 典型场景 | 单页内容提炼 | 批量页面字段提取 | 交互复杂、需要模拟点击的站点 |
| 上手成本 | 极低,会打字就行 | 中,需要基础代码能力 | 较高,涉及工具链和提示词调试 |
| 稳定性 | 低,输出格式不稳 | 较高,配合校验兜底 | 中,受视觉模型推理影响 |
| 主要开销 | 对话token | 请求加解析token | 浏览器资源加视觉模型token |
| 规模化能力 | 差 | 好 | 中等,受成本制约 |
3. 实战演示:从零抓取电商商品数据(两种方案对照)
3.1 传统方案完整流程:选择器加正则,稳但不省心
假设目标是一个商品列表页,页面里有商品名、价格、销量、评价数四类字段。传统方案的经典流程是这样的:构造请求、用选择器定位字段、翻页循环。代码长这样:
import requests from bs4 import BeautifulSoup import time headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" } session = requests.Session() session.headers.update(headers) product_list = [] for page in range(1, 6): url = f"https://example-shop.com/items?page={page}" resp = session.get(url, timeout=10) soup = BeautifulSoup(resp.text, "lxml") for item in soup.select("div.product-item"): title = item.select_one("a.product-title").get_text(strip=True) price_text = item.select_one("span.price").get_text(strip=True) sales_text = item.select_one("span.sales").get_text(strip=True) product_list.append({ "title": title, "price": price_text.replace("¥", "").replace(",", ""), "sales": sales_text, }) time.sleep(2) print(product_list)这段代码里值得注意的不是逻辑,而是细节。timeout=10必须写,防止部分页面卡住拖垮整批任务;User-Agent必须带真实值,否则很多服务端会直接拒绝;翻页之间必须sleep,否则高频请求很快触发限流。
但传统方案的坑也在这里:你看到的选择器表达式div.product-item、a.product-title都是特定站点布局的耦合产物。站点只要改一次CSS类名,这些选择器全部作废。我见过一个项目,站点改版后爬虫静默跑了一周,抓回来的数据全是空字段,直到做报表的人发现数字对不上才暴露问题。选择器方案最大的成本不是写出来的那2小时,而是后面维护它的每一分钟。
3.2 AI方案完整流程:提示词提取加JSON兜底
AI方案的流程看起来更短,但实际上对工程化的要求更高。核心逻辑是三条:裁剪、提示、校验。
裁剪这一步很多人会忽略,但绝对不能省。直接整页HTML发给大模型,一页可能几十万字符,token费用高得离谱,而且页面底部导航、广告区块、推荐位这些无关信息会干扰模型输出。先把HTML裁成正文区域,再去掉所有标签属性,只保留文本结构,这一步能省掉80%以上的token。
裁剪之后拼接提示词,我实测下来一个比较稳的模板是这样:
import requests import re import json def clean_html(html): html = re.sub(r"<script[\\s\\S]*?</script>", "", html) html = re.sub(r"<style[\\s\\S]*?</style>", "", html) # 去掉标签属性,保留文本 text = re.sub(r"<[^>]+>", " ", html) text = re.sub(r"\\s+", " ", text) return text[:8000] html = requests.get("https://example-shop.com/items", timeout=10).text content = clean_html(html) prompt = f""" 从下面的网页文本中提取商品列表,返回JSON数组。 每个商品字段为 title, price, sales。 注意:price只保留数字,不要货币符号。 网页文本: {content} """ # 调用某大模型的对话接口,temperature设置为0 response = call_llm(prompt, temperature=0) raw = response["choices"][0]["message"]["content"] # 校验:确保能解析成JSON数组 try: data = json.loads(raw) except Exception: data = extract_json_from_text(raw) # 兜底逻辑这里有几个关键点:
temperature=0至关重要,不设低的话,模型会“发挥创造力”,编出页面里不存在的价格- 提示词里明确格式要求“返回JSON数组”,并指明字段名和格式规则,这种显式约束比“帮我提取一下”要稳得多
- 裁剪后的文本我限制在8000字符以内,不是不能更长,而是这个长度内模型的提取准确率和token成本之间最平衡
另外一定要留一层兜底解析。模型偶尔会返回“好的,以下是提取结果:{...}”这种带礼貌用语的文本,直接json.loads会失败。所以要么在提示词里强调“只输出JSON”,要么代码里写一个从任意文本中提取JSON块的辅助函数,双保险。
3.3 两种方案的成本和稳定性对比
为了把两种方案说透,我算了一个实际例子。假设要抓200条商品数据,每条页面原始HTML约8万字符,裁剪后剩约4000字符。
传统方案成本:基本为零,主要花在人工写选择器和维护上。写选择器加联调大约2小时,之后每次站点改版再花几小时修。按人工成本折算,一个长期项目每年的维护成本其实相当可观。
AI方案成本:按输入token加输出token计费。输入4000字符大约折合1000到2000个token,输出一个200字符的JSON约50到100个token。200条数据的总token消耗大约在20万到40万之间,按当前主流大模型服务价格算,总金额在几十元级别。人工方面,写提示词加联调大约1小时,之后站点改版基本不需要动。
两边一对比,结论很清晰:
| 对比维度 | 传统选择器方案 | AI提示词方案 |
|---|---|---|
| 金钱成本 | 低(服务器费用为主) | 中(按token计费) |
| 初始开发时间 | 2小时以上 | 1小时以内 |
| 站点改版时 | 选择器失效,需人工修复 | 提示词通常不受影响 |
| 数据格式 | 稳定,完全可控 | 需要加一层校验兜底 |
| 适合规模 | 百页到百万页都行 | 千页以内性价比高,超过后成本飙升 |
我给它定性:AI方案的价值不是“替代传统爬虫”,而是把过去很多需要写程序解析的长尾场景,变成写提示词就能解决。本质是用算力换开发时间。前提是你对数据质量有容忍度,或者你愿意为它加一层校验程序。
4. 绕不开的拦路虎:反爬、脏数据与Token账单
4.1 反爬不是AI能解决的:请求层的三个基础设置
不管哪种AI方案,最终你都要自己发请求拿HTML,所以反爬这件事绕不开。最常见的封禁原因就三个:请求频率过高、同一IP下请求特征过于一致、缺少真实浏览器特征的请求头。
AI在这里能帮的忙非常有限,顶多是辅助生成更真实的请求头,但限速这件事必须靠工程手段解决。我的最低成本保护策略是这么做的:
import time import random # 每次请求之间的随机延迟,模拟真实用户节奏 def smart_delay(): time.sleep(random.uniform(1, 3)) # 失败重试时指数退避,而不是立即重试 def retry_with_backoff(func, max_retries=3): for attempt in range(max_retries): try: return func() except Exception: time.sleep(2 ** attempt + random.uniform(0, 1)) return None这两段代码看起来简单,但能解决80%的基础封禁问题。还有一个细节是Cookie和登录态:能用Session保持的坚决不要每次重新登录,频繁登录反而更容易触发风控。对于登录型站点,先手动过验证码,再用Session保存登录态去抓,是成本最低也最稳的方案。
4.2 脏数据治理:AI返回格式不稳定的四个解法
AI方案最大的槽点是输出不稳定,我实测下来高频问题有四类:
- 字段缺失:模型有时漏掉某条记录的某个字段
- 格式不统一:同是价格,可能输出“1,299元”也可能输出“1299.00”
- 幻觉字段:模型编造出页面里不存在的价格或销量
- JSON结构断裂:偶尔返回截断的JSON,尤其是记录多的时候
解法也相对固定:严格约束输出格式、设置JSON Schema校验、次级规则提取兜底、归一化清洗。归一化这段代码可以这么写:
import re def normalize_price(value): # 去掉货币符号和千分位逗号 value = re.sub(r"[¥$¥]", "", str(value)) value = value.replace(",", "") # 只保留数字和小数点 match = re.search(r"\\d+\\.?\\d*", value) return float(match.group()) if match else None把这段代码接在模型返回之后做一遍强制清洗,能挡住大部分格式问题。至于幻觉字段,靠的是两件事:一是temperature设低,二是数据量不大时人工抽检。我现在的习惯是每次跑完任务随机抽20条肉眼过一遍,确认没有明显编造内容再入库。
4.3 Token账单怎么算:什么时候AI方案反而亏钱
Token计费这件事很容易被低估。服务商按输入加输出总token收费,但对中文来说成本比英文更高,因为中文拆成的token数量更多。计算公式可以简化成:
- 单页token数约等于页面字符数除以3到5
- 实际费用等于单页token数乘以页数乘以单价
四舍五入估一个临界判断标准:
| 场景 | 推荐方案 |
|---|---|
| 少于200页,字段复杂,格式混乱 | 直接AI方案,省事 |
| 200到1000页,结构稳定 | 看站改版频率,高频则AI,低频则传统 |
| 超过1000页,字段固定 | 传统方案,成本优势巨大 |
| 页面结构经常变且数据量大 | 混合架构(见下文) |
我踩过的坑是曾经用AI方案跑了5000页数据,跑完一算,光token费用就顶得上一个月的服务器开销,而数据质量并没有比传统方案更高。自那以后我给自己立了一个规矩:超过1000页且结构稳定的站,优先传统方案;低于200页或者结构经常变的,直接AI方案;中间地带走混合架构。
5. 我的选型建议与适用边界
5.1 什么场景直接选传统方案
页面结构长期稳定、数据量大、字段固定且有工程团队长期维护,这种场景用AI纯属浪费钱。典型例子是抓一个成熟平台的公开接口数据,一天几万条,字段就三五个,选传统方案既快又稳。
还有一类情况也建议传统方案:数据要求实时性极高,秒级或分钟级更新。AI方案单页处理耗时通常在几秒甚至更久,完全跟不上这种节奏。传统方案加上异步请求库,一分钟可以抓几十页,性能差距很明显。
5.2 什么场景值得用AI方案
反过来说,页面结构混乱、项目周期短、临时抓取一次性需求、需要快速产出JSON给下游使用,这些场景AI方案是首选。
我举一个真实体会:有一次要抓某个活动专题页,页面里混着H1标题、活动图片、跳转链接、段落文字,结构完全没有规律,传统方案写选择器写了半小时还覆盖不全。换成AI方案,一段提示词下去,两分钟出结果,字段还全。那种页面看一眼就知道写选择器要崩溃的场景,就是AI方案的主场。
5.3 混合架构才是长期答案
用了一年多AI方案之后,我现在的做法是混合架构:传统选择器方案做主体抓取,AI方案做异常兜底。
具体逻辑是:先跑选择器解析,如果某一条数据解析出来是空或者明显不合理,就自动把这段HTML交给模型重新提取,提取结果进入人工审核队列。这样主体数据量大的部分走低成本的传统方案,异常和改版部分走AI方案兜底,两头的好处都占了。
极简伪代码长这样:
def parse_item(item_html): result = parse_with_selector(item_html) if result is None or result["price"] is None: # 选择器失败,走AI兜底 result = parse_with_llm(item_html) flag_for_manual_review(result) return result这套架构的维护成本最低,因为大部分页面不需要动用模型,只有选择器失效的边缘场景才触发AI,成本可控,数据质量也有保障。我现在的所有长期抓取项目基本都是这个结构。
最后说一点个人体会。AI爬虫工具这几年迭代很快,但本质上它解决的还是“解析”这一层的效率问题,后面接的还是请求工程、反爬对抗、数据治理这些老几样。你别指望它一步到位替你解决全部问题,更别因为工具新鲜就把原来成熟的方案推倒重来。我自己的判断标准很简单:先算清数据量,再问页面稳不稳,最后才决定用哪把刀。这个顺序反过来的人,基本都多交了一笔学费。