用 AI 做竞品调研:从抓取到对比表的完整流程

👁 55 次阅读

配图
配图

先定边界:AI 负责抽取,人负责判断

用 AI 做竞品调研,最容易犯的错是把它当成一键生成行业报告的机器。更稳的做法是把流程拆成四层:采集公开信息、结构化成字段、基于证据做判断、把判断转成行动。AI 在前两层效率最高,在第三层适合做归纳和提出假设,在第四层只能辅助,不能替代负责人拍板。竞品调研的产出不是一张漂亮表格,而是一条可追溯的证据链:每个结论都能回到原文,每个原文都记录来源页面和抓取时间。只要证据链在,后续更新和复核就有抓手。

配图
配图

第一步:把调研问题写成可验证字段

不要一开始就让 AI 收集所有竞品。先写下这次调研要支持的决策:是定价、产品定位、功能补齐,还是渠道拓展。不同决策对应不同字段。比如定价调研要关注套餐名称、计费单位、免费额度、试用条件、增购方式;定位调研要关注目标用户、使用场景、核心卖点、替代方案、信任背书。字段必须能被原文验证,避免使用『更好用』『更智能』这类无法核验的字段。建议先做一张字段卡,把维度、字段名、证据来源、AI 任务和人工校验点写清楚,再进入抓取。

维度 字段 证据来源 AI 处理 人工校验
定位 目标用户 首页、关于页、案例页 抽取用户描述并归类 是否原文明确
价值 核心卖点 功能页、首页首屏 合并同义表述 是否把通用词当差异
商业 价格表达 定价页、帮助中心 保留套餐名与计费单位 是否遗漏附加费
采用 免费试用 定价页、注册页 标记条件与限制 是否可验证
生态 集成能力 集成页、文档、应用市场 抽取集成对象 是否区分自建与第三方
风险 迁移与限制 帮助中心、条款页 提取限制条件 是否过期

第二步:确定样本框与抓取范围

竞品不要贪多。先按直接竞品、间接竞品、替代方案分层,每层选少量代表,保证覆盖不同定位即可。样本框一旦确定,就为每个竞品建立页面清单:首页、定价页、功能页、集成页、案例页、帮助中心、更新日志、应用市场评价页。只抓首页会漏掉价格限制、套餐差异和迁移成本。每个页面记录 URL、页面标题、抓取时间、语言、页面类型和选择器版本。若页面存在多语言或多地区版本,要固定一个版本做横向对比,避免把不同地区价格混在一张表里。动态渲染页面可以静态优先,确实需要浏览器再上自动化工具;抓取前查看 robots.txt 与站点条款,控制频率,做本地缓存,不绕过登录、验证码和付费墙。

第三步:合规抓取并保存原始快照

先用最小命令把公开页面保存下来。下面的示例只抓取公开页面,域名需要替换成你确认允许抓取的站点。每次抓取保留原始 HTML 和抽取后的文本,方便日后复核。

mkdir -p competitor_pages
curl -L --fail -o competitor_pages/a.html https://example.com/pricing
curl -L --fail -o competitor_pages/b.html https://example.com/features

抽取正文时,不要把导航、页脚、弹窗和重复按钮一起喂给模型。可以先去掉 script、style、nav、footer 等节点,再把正文按标题层级切块。下面是一段可运行的 Python 示例,使用 requests 和 BeautifulSoup,输出纯文本到本地文件。

import requests
from bs4 import BeautifulSoup

url = 'https://example.com/pricing
resp = requests.get(url, timeout=20)
resp.raise_for_status()
soup = BeautifulSoup(resp.text, 'html.parser')
for tag in soup(['script', 'style', 'nav', 'footer']):
    tag.decompose()
text = soup.get_text(' ', strip=True)
with open('competitor_pages/a.txt', 'w', encoding='utf-8') as f:
    f.write(text)
print(len(text))

这段代码只解决『拿到干净文本』,不解决合规与频率控制。实际使用时还要加上请求间隔、失败重试、User-Agent 说明、robots.txt 检查和页面快照哈希。哈希的作用是判断页面是否变化,不是用来替代原文。

第四步:清洗与结构化字段设计

清洗的目标不是把文字变短,而是保留可对比的语义单元。把每个页面切成块:标题块、卖点块、价格块、限制条件块、证据块。块与块之间保留来源 URL 和页面位置。字段类型也要提前约定:文本字段保留原文表述,列表字段允许一条原文对应多个卖点,证据字段必须存原句。价格字段不要急着折算成统一金额,先保留套餐名、计费单位、免费额度和限制条件,再在分析层做定性比较。下面是一份简化的字段配置示例,可以按你的调研目标增删。

fields:
  - name: product_name
    type: text
    source: title
  - name: target_user
    type: text
    source: body
  - name: core_claim
    type: list
    source: feature_section
  - name: price_text
    type: text
    source: pricing_section
  - name: trial
    type: text
    source: pricing_section
  - name: evidence
    type: quote
    source: body

字段配置要服务于对比表,不要为了全而全。一个字段如果无法从公开页面找到证据,就不要放进主表,可以放到待验证清单。结构化结果建议同时保存两份:一份是字段表,一份是证据表。字段表用于横向对比,证据表用于复核和更新。

第五步:用 AI 做字段抽取与归一

把 AI 放在字段抽取环节,而不是让它自由发挥写报告。输入要包含三样东西:字段定义、原文分块、输出格式。输出要求写死:只根据给定文本,不补充外部知识,缺失写未提及,每个结论附原句。温度调低,字段顺序固定,最好让模型分批处理页面块,避免长文本里前后矛盾。下面是一段提示词模板,可直接改成你的字段。

你是竞品调研助手。请只根据下面文本抽取字段,不得补充外部知识。字段包括:产品名、目标用户、核心卖点、价格表达、免费试用、集成能力、证据原句。缺失字段写 未提及。每个结论后面附原句。输出 Markdown 表格。文本如下:

拿到输出后不要直接贴进总表。先做程序化校验:字段是否齐全、证据是否为空、原句是否能在原文中找到、同一页面是否出现矛盾表述。再用 AI 做一次同义归一,例如把『团队协作』『多人协同』合并成同一能力标签,但归一规则要人审。价格和限制条件尽量保留原文,不要让模型替你计算或推断。模型擅长把散落信息整理成可比结构,不擅长判断哪个卖点真正影响购买。

第六步:人工校验与证据链管理

人工校验至少做三查。第一查原文是否存在:把模型给出的证据原句回到页面搜索,找不到就标记为待核。第二查语义是否一致:原文说的是『支持导入』,模型不能写成『支持双向同步』。第三查时效:页面改版、套餐调整、功能下线都会让旧结论失效。每个结论建议附上来源 URL、页面标题、抓取时间、原文片段和置信度。置信度可以分为高、中、低:原文直接写明为高,需要跨页推断为中,只有间接线索为低。低置信度结论可以保留,但不要进入最终决策表的主结论。
证据表比对比表更重要。对比表是给人看的,证据表是给复核和更新用的。每次更新只重抓变化页面,用哈希或标题差异定位变化,再让 AI 重新抽取受影响字段。不要把历史证据覆盖掉,保留版本号或抓取批次。这样当同事问『这个结论从哪来』时,你能直接给出原文,而不是回答『模型说的』。

第七步:生成可读的竞品对比表

对比表不要把所有字段堆成几十列。建议分三层:定位层看目标用户、场景、核心卖点;能力层看关键功能、集成、限制条件;商业层看价格表达、试用、合同与迁移成本。每一行只回答一个对比问题,列不要太多,给证据和判断留位置。表里的竞品名称可以用竞品 A、竞品 B、竞品 C 代替,等证据确认后再替换成真实名称。下面是一个对比表骨架,重点是结构,不是填满所有格子。

对比维度 竞品 A 竞品 B 竞品 C 证据与备注
目标用户 原文摘录 原文摘录 原文摘录 链接与原句
核心卖点 原文摘录 原文摘录 原文摘录 区分差异点与通用词
价格表达 套餐名与计费单位 套餐名与计费单位 套餐名与计费单位 保留原文,不折算金额
免费试用 条件与限制 条件与限制 条件与限制 是否需绑定支付方式
集成能力 集成对象 集成对象 集成对象 区分官方集成与第三方
迁移与限制 限制条件 限制条件 限制条件 来自帮助中心或条款页

生成表格时,可以让 AI 先输出草稿,但必须保留证据列。没有证据的格子宁可空着,也不要让模型补齐。对比表的价值在于暴露差异和空白,不在于看起来完整。表格完成后,再做一次反向检查:每个差异点是否能在原文中找到支撑,是否把不同地区、不同套餐或不同版本混在一起。

第八步:把对比表变成行动清单

对比表只是中间产物。下一步是把差异翻译成可验证的行动假设。比如某个竞品在首屏反复强调某个场景,而你的页面没有对应证据,就可以提出『补充该场景案例』的假设;某个竞品把试用条件写得很清楚,而你的注册流程含糊,就可以提出『降低试用解释成本』的假设。注意,这些只是假设,不是结论。每条行动写清楚:要验证什么、需要什么证据、由谁负责、多久复核。AI 可以帮你把表格转成问题清单,但不能替你决定优先级。优先级要结合你的用户访谈、销售反馈和产品阶段来判断。
行动清单建议分三类:内容补强、产品能力、增长实验。内容补强对应官网表达和案例证据;产品能力对应功能缺口和集成需求;增长实验对应试用、定价表达和转化路径。每类只保留少量最值得验证的条目,避免把竞品调研变成无限扩张的待办列表。

第九步:常见坑与质量指标

常见坑主要有几类。抓取坑:只抓首页、忽略帮助中心、被动态渲染和 cookie 弹窗干扰、把多语言页面混在一起。AI 坑:把营销话术当事实、字段漂移、缺失字段被模型编造、长文本前后矛盾。流程坑:没有证据表、没有抓取时间、没有版本记录,导致结论无法复核。要减少这些问题,可以把质量指标固定下来:字段完整率、证据覆盖率、人工复核一致率、页面新鲜度、低置信度结论占比。指标不需要很复杂,但每次调研都按同一口径记录,才能比较不同批次的质量。
另一个容易被忽略的问题是样本偏差。只选头部竞品,会看不到细分市场的差异;只选熟悉的产品,会漏掉替代方案。样本框要写明入选理由和排除理由,后续复盘时才知道结论的适用范围。AI 可以提高处理速度,但样本选择仍然是人的判断。

第十步:一套可复用的执行流程

把上面的步骤压缩成可复用流程:先写决策问题和字段卡;再确定竞品分层与页面清单;接着合规抓取并保存原文快照;清洗成块并结构化;用 AI 抽取字段和证据;人工三查并标注置信度;生成分层对比表;最后把差异转成行动假设。每次更新只重抓变化页面,保留旧版本证据。团队协作时,字段定义、提示词、归一规则和证据格式都要版本化,否则不同人跑出来的表无法合并。
如果只想先跑通最小闭环,可以从一个决策问题、少量竞品和一张字段卡开始。先保证每个结论有原文,再追求覆盖度。流程跑顺后,再把抓取脚本、提示词和表格模板固化下来。AI 工具会变,但证据链和字段纪律不会过时。

结尾建议:先做一张可复核的小表

建议你今天就用一个明确的决策问题开一张小表:选少量直接竞品,列定位、价格表达、试用条件、集成能力、迁移限制五类字段,每个字段只填原文摘录和来源链接。先手动抓取公开页面并保存快照,再用上面的提示词让 AI 抽取,最后人工核对每一条证据。不要追求一次覆盖所有竞品,先把『原文可追溯、字段可比较、结论可复核』这三件事跑通。等这张小表稳定后,再扩展页面清单和自动化脚本。

订阅 AI 百事知

每周精选 AI 工具评测、行业资讯与使用教程,第一时间送达。

🔗 相关阅读(你可能还想看)

📄 Perplexity Pro 学生免费一年怎么领:验证流程、失败排查与免费版区别全解
📄 AI效率工具提升办公效率的实战方法
📄 Notion AI 数据库自动化实战教程:从零搭建智能工作流到自动化闭环
📄 2026年AI生成PPT工具实战教程:从选型到精修的完整工作流指南
📄 ChatGPT Projects 实战教程:从零建立持续工作流,告别重复上传与提示词
📄 Notion AI 完整使用教程:从零开始掌握 AI 写作、数据库自动化与团队知识库构建(2026 最新版)
📄 NotebookLM 使用教程:从入门到精通的完整指南(2026年最新版)
📄 ChatGPT Slides 实战教程:6 步把一次对话变成团队可协作的演示稿,导出 PPTX 前先验这三样(2026 官方指南)
OpenAI 10 月中旬上线的 ChatGPT Slides,把演示稿从单人文件搬进 Space:从对话、文件、大纲或
📄 长文档拆解成结构化大纲的提示词工程实操教程
本文给出把长文档拆成结构化大纲的可复制流程:先定字段与层级,再按标题和段落分块,用抽取式提示词生成块级要点,随后分批归并
🤖 想直接和 AI 对话?
免费体验 DeepSeek V4 等顶级模型,无需注册,随问随答
🎯 立即体验 AI 工具

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

🤖 嘟嘟客服
滚动至顶部
🤖 嘟嘟客服
🤖 嘟嘟客服
';i.value='';m.innerHTML+='
...
';fetch('/dify-chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({query:q,user:'w'+Date.now()})}).then(function(r){return r.json()}).then(function(d){var a=d.answer||'暂时无法回复';m.removeChild(m.lastChild);m.innerHTML+='
'+a+'
'}).catch(function(){m.removeChild(m.lastChild);m.innerHTML+='
网络异常
'})">发送