You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展Manifest V3无法访问DOM,如何获取供应商网站数据?

解决方案

方案1:Content Scripts + 消息通信(最推荐,符合MV3规范)

在Manifest V3中,chrome.tabs.executeScript()被移除,但Content Scripts依然拥有直接访问目标页面DOM的权限,可通过提前配置Content Scripts,配合后台Service Worker的消息机制实现数据获取:

  1. 配置Manifest.json
    在manifest.json中声明匹配供应商网站的Content Scripts:

    {
      "manifest_version": 3,
      "content_scripts": [
        {
          "matches": ["https://供应商域名1/*", "https://供应商域名2/*"], // 替换为实际供应商网址
          "js": ["content-script.js"],
          "run_at": "document_idle" // 页面加载完成后执行
        }
      ],
      "background": {
        "service_worker": "background.js"
      },
      "permissions": ["tabs", "scripting"]
    }
    
  2. 编写Content Script(content-script.js)
    监听后台消息,收到指令后获取DOM中的价格和交期数据并返回:

    chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
      if (message.action === 'fetchProductInfo') {
        // 根据实际页面DOM结构修改选择器
        const price = document.querySelector('.product-price').textContent.trim();
        const deliveryDate = document.querySelector('.delivery-date').textContent.trim();
        sendResponse({ price, deliveryDate });
      }
      return true; // 保持消息通道开放,支持异步返回
    });
    
  3. 后台Service Worker(background.js)
    创建产品页面标签后,向该标签页发送消息触发数据获取:

    // 示例:创建产品页面标签并获取数据
    async function fetchProduct(productUrl) {
      const tab = await chrome.tabs.create({ url: productUrl, active: false });
      // 等待标签页加载完成
      await new Promise(resolve => {
        const listener = (tabId, changeInfo) => {
          if (tabId === tab.id && changeInfo.status === 'complete') {
            chrome.tabs.onUpdated.removeListener(listener);
            resolve();
          }
        };
        chrome.tabs.onUpdated.addListener(listener);
      });
      // 向标签页发送消息
      const result = await chrome.tabs.sendMessage(tab.id, { action: 'fetchProductInfo' });
      console.log('产品信息:', result);
      // 可选:关闭标签页
      await chrome.tabs.remove(tab.id);
      return result;
    }
    

方案2:使用Chrome Debugger API(适合动态注入场景)

如果供应商网站数量多、规则不固定,无法提前配置Content Scripts,可通过chrome.debugger API调用Chrome DevTools Protocol(CDP)动态执行脚本获取DOM数据,该方式复用浏览器会话,完美适配复杂认证流程:

  1. 添加权限
    在manifest.json中添加debugger权限:

    {
      "permissions": ["debugger", "tabs"]
    }
    
  2. 后台Service Worker实现代码

    async function fetchProductViaDebugger(productUrl) {
      const tab = await chrome.tabs.create({ url: productUrl, active: false });
      // 连接标签页调试器
      await chrome.debugger.attach({ tabId: tab.id }, '1.3');
      // 启用Runtime域
      await chrome.debugger.sendCommand({ tabId: tab.id }, 'Runtime.enable');
      // 等待页面加载完成并执行脚本
      const productInfo = await new Promise(resolve => {
        chrome.debugger.onEvent.addListener(async (source, method, params) => {
          if (source.tabId === tab.id && method === 'Runtime.executionContextCreated') {
            // 执行脚本获取DOM数据
            const result = await chrome.debugger.sendCommand(
              { tabId: tab.id },
              'Runtime.evaluate',
              {
                expression: `
                  ({
                    price: document.querySelector('.product-price').textContent.trim(),
                    deliveryDate: document.querySelector('.delivery-date').textContent.trim()
                  })
                `
              }
            );
            // 清理资源并返回结果
            await chrome.debugger.detach({ tabId: tab.id });
            await chrome.tabs.remove(tab.id);
            resolve(result.result.value);
          }
        });
      });
      console.log('产品信息:', productInfo);
      return productInfo;
    }
    

方案3:批量处理优化(可选)

如果需要批量处理大量产品,可优化流程提升效率:

  • 复用已登录的供应商标签页,避免重复创建新标签页
  • 使用chrome.tabs.query()查找已打开的目标页面,直接发送消息获取数据
  • 限制同时打开的标签页数量,避免浏览器性能过载

内容的提问来源于stack exchange,提问作者MrFrederic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 19:55:17