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

如何将Puppeteer爬取的电商价格结果在HTML服务器中展示?

如何将Puppeteer爬取的数据展示在HTML页面中

核心问题分析

你的代码是Node.js控制台脚本,仅能在终端输出结果。要在HTML页面展示数据,需搭建后端服务执行爬取逻辑,再通过HTTP接口将数据传递给前端页面渲染。

解决方案步骤

1. 修复并重构Scrape函数

先修正原有代码的关键问题,并让函数返回爬取结果(而非直接打印):

  • 补充switch语句中缺失的break,避免配置被覆盖
  • 给browser.close()添加await,确保浏览器正常关闭
  • 封装结果对象,包含站点、价格、折扣价和错误信息

修改后的scrape.js:

const puppeteer = require("puppeteer");

const scrape = async (site, value) => {
  let uSite = "https://www.cosmetica.com.tr/arama/hizliErisim.aspx?tip=U&lang=tr-TR&srt=&text=";
  let elWay = "#ctl00_u30_ascArama_urun_ascUrunList_rptDestUrun_ctl00_pnlNormal";
  let elDiscountWay = "#ctl00_u30_ascArama_urun_ascUrunList_rptDestUrun_ctl00_pnlIndirim";

  switch (site) {
    case "Cosmetica":
      uSite = "https://www.cosmetica.com.tr/arama/hizliErisim.aspx?tip=U&lang=tr-TR&srt=&text=";
      elWay = "#ctl00_u30_ascArama_urun_ascUrunList_rptDestUrun_ctl00_pnlNormal";
      elDiscountWay = "#ctl00_u30_ascArama_urun_ascUrunList_rptDestUrun_ctl00_pnlIndirim";
      break;
    case "Gratis":
      uSite = "https://www.gratis.com/search/";
      elWay = "div.price.ng-star-inserted > div";
      elDiscountWay = "div.price-w-card.ng-star-inserted > div";
      break;
    case "Watsons":
      uSite = "https://www.watsons.com.tr/search?searchType=manual&text=";
      elWay = "#products-content-list > e2-content-list > v-root > div > div > v-slot > v-slot-assigned-content > div > div > e2-impression-tracker > div > div.product-tile__details-and-price > div.product-tile__price > div > div > e2-price-badge > div";
      elDiscountWay = "#products-content-list > e2-content-list > v-root > div > div > v-slot > v-slot-assigned-content > div > div > e2-impression-tracker > div > div.product-tile__details-and-price > div.product-tile__price > div > div > div > div > e2-price-badge > div";
      break;
    case "Rossmann":
      uSite = "https://www.rossmann.com.tr/catalogsearch/result/?q=";
      elWay = "#eln-product-products > div > ol > li:nth-child(1) > div.product-item-info > div > div.price-box.price-final_price > span > span > p > span.price.desktopPrice";
      elDiscountWay = "#eln-product-products > div > ol > li:nth-child(1) > div.product-item-info > div > div.price-box.price-final_price > span > div > span.price";
      break;
    default:
      break;
  }

  const url = `${uSite}${value}`;
  let result = { site, price: null, discountPrice: null, error: null };

  try {
    const browser = await puppeteer.launch({
      headless: true,
      executablePath: './chrome/win64-116.0.5793.0/chrome-win64/chrome.exe'
    });
    const page = await browser.newPage();
    await page.goto(url, { waitUntil: 'networkidle2' });

    const element = await page.$(elWay);
    const dElement = await page.$(elDiscountWay);

    if (element) result.price = await page.evaluate(el => el.textContent.trim(), element);
    if (dElement) result.discountPrice = await page.evaluate(el => el.textContent.trim(), dElement);
    if (!result.price && !result.discountPrice) result.error = "无法找到价格元素";

    await browser.close();
  } catch (err) {
    result.error = err.message;
    console.error(`${site} 爬取失败:`, err);
  }

  return result;
};

module.exports = scrape;

2. 搭建Express后端服务

安装Express依赖:

npm install express

创建server.js,编写HTTP接口:

const express = require('express');
const scrape = require('./scrape');

const app = express();
const port = 3000;

// 允许本地跨域测试
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Methods', 'GET');
  next();
});

// 爬取接口:接收商品ID参数
app.get('/scrape', async (req, res) => {
  const productId = req.query.id;
  if (!productId) return res.status(400).json({ error: '请提供商品ID' });

  // 并行爬取四个站点
  const results = await Promise.all([
    scrape("Cosmetica", productId),
    scrape("Gratis", productId),
    scrape("Watsons", productId),
    scrape("Rossmann", productId)
  ]);

  res.json(results);
});

app.listen(port, () => {
  console.log(`服务器运行在 http://localhost:${port}`);
});

3. 编写前端HTML页面

创建index.html,实现交互和数据渲染:

<!DOCTYPE html>
<html lang="tr">
<head>
  <meta charset="UTF-8">
  <title>商品价格查询</title>
  <style>
    .result-container {
      margin-top: 20px;
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
      gap: 15px;
    }
    .card {
      border: 1px solid #ddd;
      padding: 15px;
      border-radius: 8px;
    }
    .error {
      color: #dc3545;
    }
  </style>
</head>
<body>
  <h1>商品价格查询</h1>
  <div>
    <input type="text" id="productId" placeholder="输入商品ID(例如:8697432090277)">
    <button onclick="fetchPrices()">查询价格</button>
  </div>
  <div id="results" class="result-container"></div>

  <script>
    async function fetchPrices() {
      const productId = document.getElementById('productId').value.trim();
      const resultsDiv = document.getElementById('results');
      resultsDiv.innerHTML = '<p>正在查询...</p>';

      if (!productId) {
        resultsDiv.innerHTML = '<p class="error">请输入商品ID</p>';
        return;
      }

      try {
        const response = await fetch(`http://localhost:3000/scrape?id=${productId}`);
        const data = await response.json();

        let html = '';
        data.forEach(item => {
          html += `
            <div class="card">
              <h3>${item.site}</h3>
              ${item.error ? `<p class="error">错误: ${item.error}</p>` : ''}
              ${item.price ? `<p>原价: ${item.price}</p>` : ''}
              ${item.discountPrice ? `<p>折扣价: ${item.discountPrice}</p>` : ''}
            </div>
          `;
        });
        resultsDiv.innerHTML = html;
      } catch (err) {
        resultsDiv.innerHTML = `<p class="error">查询失败: ${err.message}</p>`;
      }
    }
  </script>
</body>
</html>

运行步骤

  1. 将上述三个文件放在同一目录下
  2. 启动后端服务:node server.js
  3. 用浏览器打开index.html,输入商品ID点击查询即可展示结果

注意事项

  • 确保Chrome可执行文件路径正确,或删除executablePath让Puppeteer自动下载Chromium
  • 部分站点有反爬机制,可添加用户代理、页面延迟等策略避免被拦截
  • 生产环境需替换Access-Control-Allow-Origin: *为具体域名,保障安全性

内容的提问来源于stack exchange,提问作者Batu A.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 20:13:12