从零开发 ReviewIQ:一款接入 AI 的亚马逊评论情报分析 Chrome 扩展(完整实战)

本文记录了我从零开发一款面向亚马逊卖家的 Chrome 扩展全过程——它能自动抓取商品评论,结合 GPT-4o / Claude 生成竞品弱点分析、产品健康评分和用户画像洞察报告,直接嵌入亚马逊页面展示。


这是执行效果图

一、为什么要做这个工具?

做亚马逊的卖家朋友都知道,评论是利润的风向标

  • 竞品差评多 = 你的选品机会
  • 自己差评多 = 退货率飙升的预警
  • 用户反复提到某个需求 = 下一款爆品的灵感

但手动翻几百条评论太低效了。市面上的工具(Helium 10、Jungle Scout)要么贵、要么不够智能。

所以我做了 ReviewIQ —— 一个直接嵌入亚马逊页面的 AI 情报面板。


二、产品定位:不是工具,是决策情报

三大核心视图:

视图 功能 价值
🎯 竞品弱点透视 差评词云、1-3星归类、AI弱点排序、竞争策略建议 精准选品
🩺 产品体检报告 AI健康评分(0-100)、风险识别、退货原因、紧急度排序 预防亏损
👥 用户画像洞察 AI用户画像、未满足需求、市场机会、痛点句挖掘 发现蓝海

核心理念:这不是工具,而是一份直指利润的决策情报。


三、技术架构总览

┌─────────────────────────────────────────────────────┐
│                 Chrome Extension (MV3)               │
├──────────┬───────────┬──────────┬───────────────────┤
│content.js│  panel.js │ popup.js │    options.js     │
│ DOM抓取  │ 页内面板  │ 快捷入口 │   API Key配置     │
├──────────┴───────────┴──────────┴───────────────────┤
│            background.js (Service Worker)             │
│       消息中转 · AI API 调用 · 数据缓存               │
├─────────────────────────────────────────────────────┤
│        OpenAI API  /  Anthropic Claude API           │
└─────────────────────────────────────────────────────┘

技术选型:

  • Chrome Extension Manifest V3(最新标准,2024+ 必须)
  • 纯 Vanilla JS(无框架依赖,加载快、包体小、审核易通过)
  • Service Worker 做 API 代理(解决 content script CORS 限制)
  • chrome.storage.sync 持久化用户配置(跨设备同步)
  • CSS 命名空间隔离#amz-iq- 前缀,不污染亚马逊页面)

四、项目结构

chrome/
├── manifest.json          # MV3 扩展配置(权限、content_scripts、host_permissions)
├── background.js          # Service Worker:消息中转 + AI API 调用
├── content.js             # 注入亚马逊页面:DOM 评论抓取 + 解析
├── panel.js               # 页内情报面板:三大分析视图 + AI 报告渲染
├── panel.css              # 面板样式(z-index 顶层 + 命名空间隔离)
├── popup.html             # 扩展弹窗 UI(快捷入口)
├── popup.js               # 弹窗逻辑(注入 + 打开面板)
├── options.html           # 设置页 UI(API Key 配置)
├── options.js             # 设置页逻辑
└── icons/                 # 扩展图标(16/48/128px)
    ├── icon16.png
    ├── icon48.png
    └── icon128.png

五、核心实现拆解

5.1 Manifest V3 配置

{
  "manifest_version": 3,
  "name": "ReviewIQ · Amazon Seller Insights",
  "version": "1.0.0",
  "permissions": ["activeTab", "scripting", "storage", "tabs"],
  "host_permissions": [
    "*://*.amazon.com/*",
    "*://*.amazon.co.uk/*",
    "*://*.amazon.de/*",
    "*://*.amazon.co.jp/*",
    "https://api.openai.com/*",
    "https://api.anthropic.com/*"
  ],
  "options_page": "options.html",
  "background": { "service_worker": "background.js" },
  "content_scripts": [{
    "matches": ["*://*.amazon.com/*", "*://*.amazon.co.uk/*"],
    "js": ["content.js", "panel.js"],
    "css": ["panel.css"],
    "run_at": "document_idle"
  }]
}

关键点:

  • host_permissions 要覆盖所有亚马逊站点 + AI API 域名
  • content_scripts 里同时注入抓取逻辑和面板 UI
  • options_page 注册设置页让用户填 API Key

5.2 评论抓取:兼容新旧版亚马逊 DOM

亚马逊页面结构经常变动,我的解决方案是广谱选择器 + 属性模糊匹配 + 最长文本兜底三层保障:

// 第一层:广谱容器选择器
const REVIEW_SELECTORS = [
  '[data-hook="review"]',
  '[data-hook="cmps-review"]',
  'li[id^="customer_review"]',
  'div[id^="customer_review"]',
  '[data-cel-widget^="customer_review"]'
].join(', ');

const nodes = document.querySelectorAll(REVIEW_SELECTORS);
// 第二层:字段提取用属性后缀/子串匹配
let bodyEl =
  el.querySelector('[data-hook="review-body"] span') ||
  el.querySelector('[data-hook$="body"]') ||
  el.querySelector('[data-hook$="body-content"]') ||
  el.querySelector('[data-hook*="review-text"]') ||
  el.querySelector('.review-text-content');
// 第三层:终极兜底 —— 取容器内最长的叶子文本
if (!body) {
  const candidates = el.querySelectorAll('span, p, div');
  let longest = '';
  candidates.forEach((c) => {
    // 只取叶子节点(不包含子元素的节点)
    if (c.querySelector('span,p,div')) return;
    const t = c.textContent.trim();
    if (t.length > longest.length) longest = t;
  });
  if (longest.length > 16) body = longest;
}

为什么要这样设计? 因为亚马逊 2024-2025 年把 data-hook="review-body" 改成了其他名字,如果你只写死选择器,随时可能抓到 0 条。

5.3 多页抓取 + 反爬检测

async function scrapeAllReviews({ asin, maxPages, sortBy, onProgress }) {
  // Step 0:先扫当前 DOM(不需要 fetch,立即可用)
  const domReviews = scrapeReviewsFromRoot(document);
  onProgress({ source: 'dom', pageCount: domReviews.length });

  // Step 1:fetch 多页 /product-reviews/<ASIN>
  for (let page = 1; page <= maxPages; page++) {
    const url = `https://www.amazon.com/product-reviews/${asin}` +
      `?pageNumber=${page}&sortBy=${sortBy}`;
    const resp = await fetch(url);
    const html = await resp.text();
    const doc = new DOMParser().parseFromString(html, 'text/html');

    // 反爬检测
    if (isBlockedPage(doc)) {
      result.blocked = true;
      break;
    }

    const pageReviews = scrapeReviewsFromRoot(doc);
    allReviews.push(...pageReviews);
    onProgress({ page, pageCount: pageReviews.length, total: allReviews.length });
  }
}

// 登录墙 / 验证码检测
function isBlockedPage(doc) {
  return !!(
    doc.querySelector('#captchacharacters') ||
    doc.querySelector('form[action*="signin"]') ||
    doc.title?.includes('Robot Check')
  );
}

5.4 页内面板注入

不用传统 popup 弹窗,而是直接注入到亚马逊页面里,卖家不需要切换窗口:

// 右下角悬浮按钮(FAB)
const fab = document.createElement('div');
fab.id = 'amz-iq-fab';
fab.textContent = 'IQ';
document.documentElement.appendChild(fab);

// 右侧抽屉式面板
const panel = document.createElement('div');
panel.id = 'amz-iq-panel';
document.documentElement.appendChild(panel);

// 点击打开/关闭
fab.addEventListener('click', () => panel.classList.add('open'));

CSS 关键样式:

#amz-iq-fab {
  position: fixed;
  right: 22px; bottom: 24px;
  width: 56px; height: 56px;
  z-index: 2147483646; /* 顶层,不被遮挡 */
  background: #f97316;
  border-radius: 50%;
  cursor: pointer;
}

#amz-iq-panel {
  position: fixed;
  top: 0; right: 0;
  width: 460px; height: 100vh;
  z-index: 2147483647;
  transform: translateX(100%); /* 默认隐藏 */
  transition: transform .3s ease;
}

#amz-iq-panel.open {
  transform: translateX(0); /* 滑入 */
}

5.5 AI 分析:GPT-4o / Claude 双引擎

核心设计:在 Service Worker 中调用 API,避免 content script 的 CORS 限制。

评论压缩(控制 token 用量):

function compressReviews(reviews, maxChars = 12000) {
  // 优先保留差评(分析价值最高),好评只取少量对比
  const neg = reviews.filter(r => r.rating <= 3);
  const pos = reviews.filter(r => r.rating >= 4).slice(0, 5);
  const selected = [...neg, ...pos];

  let result = '';
  for (const r of selected) {
    const line = `[${r.rating}★] ${(r.title || '').slice(0, 60)} | ${(r.body || '').slice(0, 200)}\n`;
    if (result.length + line.length > maxChars) break;
    result += line;
  }
  return result;
}

结构化 Prompt(让 AI 直接输出可解析的 JSON):

function buildPrompt(meta, reviewsText) {
  return `你是一位亚马逊电商数据分析专家。以下是商品 "${meta.productTitle}" (ASIN: ${meta.asin}) 的用户评论摘录。

评论数据:
${reviewsText}

请输出严格 JSON 格式的分析报告:
{
  "competitor": {
    "weaknesses": [{"point": "具体弱点", "severity": "high/medium/low", "evidence": "评论原文片段", "count": 出现次数}],
    "exploitStrategy": "竞品如何利用这些弱点的策略建议"
  },
  "health": {
    "score": 0-100整数,
    "risks": [{"issue": "风险描述", "urgency": "critical/high/medium/low", "action": "建议行动"}],
    "returnReasons": ["退货原因1", "退货原因2"],
    "summary": "产品健康总结"
  },
  "insight": {
    "personas": [{"label": "用户群标签", "description": "特征描述", "needs": "核心诉求"}],
    "unmetNeeds": ["需求1", "需求2"],
    "opportunities": ["市场机会1", "市场机会2"],
    "summary": "用户洞察总结"
  }
}

要求:所有文本使用中文,仅输出 JSON。`;
}

双 API 支持

// OpenAI
async function callOpenAI(cfg, prompt) {
  const resp = await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${cfg.apiKey}`
    },
    body: JSON.stringify({
      model: cfg.model || 'gpt-4o-mini',
      messages: [{ role: 'user', content: prompt }],
      max_tokens: 2000,
      temperature: 0.4
    })
  });
  const data = await resp.json();
  return data.choices?.[0]?.message?.content || '';
}

// Claude
async function callClaude(cfg, prompt) {
  const resp = await fetch('https://api.anthropic.com/v1/messages', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': cfg.apiKey,
      'anthropic-version': '2023-06-01'
    },
    body: JSON.stringify({
      model: cfg.model || 'claude-sonnet-4-20250514',
      max_tokens: 2000,
      messages: [{ role: 'user', content: prompt }]
    })
  });
  const data = await resp.json();
  return data.content?.[0]?.text || '';
}

5.6 本地统计分析(无需 AI 也能用)

即使不配置 API Key,面板也能给出基础分析:

// 差评关键词词频
function wordFreq(reviews, { ratingMax = 3 }) {
  const map = new Map();
  reviews.forEach((r) => {
    if (r.rating > ratingMax) return;
    tokenize(`${r.title} ${r.body}`).forEach((w) =>
      map.set(w, (map.get(w) || 0) + 1)
    );
  });
  return [...map.entries()].sort((a, b) => b[1] - a[1]);
}

// 紧急度评分 = (5 - 评分) × (1 + 有用数) × 时间衰减
function urgencyScore(r) {
  const days = (Date.now() - parseDateMs(r.date)) / 86400000;
  const decay = days < 7 ? 1.5 : days < 30 ? 1 : days < 90 ? 0.6 : 0.3;
  const sev = Math.max(0, 5 - (r.rating || 5));
  return sev * (1 + (r.helpful || 0)) * decay;
}

// 痛点句提取:从差评里找包含转折/否定关键词的句子
const PAIN_HINTS = /\b(but|however|wish|disappointed|broke|doesn't|can't|return|waste|poor)\b/i;
function painSentences(reviews, limit = 8) {
  const out = [];
  for (const r of reviews) {
    if (r.rating > 3 || !r.body) continue;
    const sents = r.body.split(/(?<=[.!?])\s+/);
    for (const s of sents) {
      if (s.length > 14 && PAIN_HINTS.test(s)) {
        out.push({ s, rating: r.rating, helpful: r.helpful || 0 });
      }
    }
  }
  return out.sort((a, b) => b.helpful - a.helpful).slice(0, limit);
}

5.7 消息通信机制

Chrome Extension 各模块通过消息传递协作:

// panel.js → background.js(请求 AI 分析)
const resp = await chrome.runtime.sendMessage({
  type: 'AI_ANALYZE',
  payload: { meta, reviews }
});

// background.js 监听并处理
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.type === 'AI_ANALYZE') {
    runAiAnalysis(msg.payload.meta, msg.payload.reviews)
      .then(report => sendResponse({ ok: true, data: report }))
      .catch(e => sendResponse({ ok: false, error: e.message }));
    return true; // 保持异步通道
  }
});

六、AI 报告渲染效果

抓取完成后,面板会显示 loading 动画,5-15 秒后 AI 报告出现在各 Tab 顶部:

竞品弱点 Tab:

  • 🤖 AI 竞品弱点深度分析(按严重程度排序的弱点卡片)
  • 🎯 AI 竞争策略建议

体检报告 Tab:

  • 🤖 AI 产品健康评估(0-100 分圆环 + 总结)
  • 🚨 AI 风险识别(带紧急度标签的风险列表)
  • 📦 AI 识别的退货原因

用户洞察 Tab:

  • 🤖 AI 用户洞察总结
  • 👤 AI 用户画像(3-4 个典型用户群)
  • 💡 AI 识别的未满足需求
  • 🚀 AI 市场机会

AI 报告卡片使用紫色左边框 + 渐变背景区分,视觉上与本地统计分析明确分层。


七、踩坑记录 & 解决方案

# 问题 原因 解决方案
1 _locales subtree is missing 加载失败 manifest 声明了 default_locale 但没创建 _locales 文件夹 移除 default_locale 字段
2 评论抓取始终 0 条 新版亚马逊把 review-body 的 data-hook 名改了 [data-hook$="body"] 模糊匹配 + 最长文本兜底
3 面板注入后打不开 panel.js 有路径白名单 + popup 消息链路不通 移除白名单 + 暴露全局 window.__AMZ_IQ_PANEL__ API + popup 多级兜底打开
4 AI API 调用 CORS 报错 content script 无法跨域请求 所有 API 调用放到 background Service Worker
5 Service Worker 里 fetch 也被拦截 没有在 host_permissions 里声明 API 域名 加上 https://api.openai.com/*https://api.anthropic.com/*
6 AI 返回的 JSON 解析失败 模型有时候用 ` ```json ````包裹输出 正则提取 fence 里的内容再 JSON.parse
7 部分页面评论区在 iframe 里 亚马逊某些布局把评论放在 iframe 中渲染 添加 diagnoseDom() 诊断函数检测 iframe 列表

八、如何本地运行

# 1. 克隆/下载项目到本地
# 2. 打开 Chrome,访问 chrome://extensions
# 3. 开启右上角「开发者模式」
# 4. 点击「加载已解压的扩展程序」→ 选择项目文件夹
# 5. 右键扩展图标 → 选项 → 填入 API Key
# 6. 打开任意亚马逊商品页 → 点击右下角橙色 IQ 按钮
# 7. 点击「抓取并分析」→ 等待结果

推荐模型配置:

模型 优势 每次成本
gpt-4o-mini 性价比最高、速度快 ≈ ¥0.01
gpt-4o 分析更全面 ≈ ¥0.05
claude-sonnet-4-20250514 深度分析、中文好 ≈ ¥0.03

九、总结

这个项目让我深入实践了:

  1. Chrome Extension MV3 开发全流程(从 manifest 配置到 Service Worker 通信)
  2. 复杂 DOM 解析的鲁棒性设计(多选择器 + 模糊匹配 + 兜底策略)
  3. LLM API 工程化接入(prompt 设计、token 控制、JSON 解析容错)
  4. 页内 UI 注入(CSS 隔离、z-index 管理、抽屉动画)
  5. 产品思维(不只是技术实现,还要想清楚商业闭环)

如果你也是亚马逊卖家、对 Chrome 扩展开发或 AI 应用感兴趣,欢迎评论区交流!


觉得有帮助的话,点个赞 👍 收藏一下吧!


---
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐