HOOOS

电商价格监控?手把手教你用Playwright搭一套!

0 49 数据猎手老王 Playwright电商价格监控自动化测试
Apple

别再手动刷商品价格啦!作为电商运营,你是不是每天都要盯着竞品的价格变动?手动记录,效率低不说,还容易出错。今天,我就教你用Playwright,轻松搭建一套自动化电商价格监控系统,让你彻底解放双手!

为什么选择Playwright?

你可能会问,市面上自动化测试工具那么多,为啥偏偏要选Playwright?原因很简单:

  • 支持多浏览器: Chrome、Firefox、Safari、Edge,主流浏览器全覆盖,保证监控的全面性。
  • 跨平台: Windows、macOS、Linux,无论你用什么操作系统,都能轻松运行。
  • 强大的选择器: CSS、XPath、文本,各种选择器应有尽有,轻松定位到你想要监控的价格元素。
  • 自动等待: 自动等待元素加载,避免因网络延迟导致的错误。
  • 易于使用: API简洁明了,上手快,学习成本低。

准备工作

在开始之前,你需要先安装Node.js和Playwright。如果你已经安装了Node.js,可以直接使用npm安装Playwright:

npm install -D @playwright/test

安装完成后,运行以下命令,安装浏览器驱动:

npx playwright install

核心代码:价格抓取

接下来,我们来编写核心代码,实现价格抓取功能。这里以某电商网站为例,假设我们要监控商品的价格元素CSS选择器是.price。代码如下:

const { chromium } = require('playwright');

async function getPrice(url) {
  const browser = await chromium.launch();
  const page = await browser.newPage();
  await page.goto(url);
  // 等待价格元素加载
  await page.waitForSelector('.price');
  // 获取价格文本
  const price = await page.$eval('.price', el => el.innerText);
  await browser.close();
  return price;
}

// 示例URL
const productUrl = 'https://www.example.com/product/123';

getPrice(productUrl)
  .then(price => {
    console.log(`商品价格:${price}`);
  })
  .catch(error => {
    console.error('抓取价格失败:', error);
  });

这段代码做了什么?

  1. 启动浏览器: 使用chromium.launch()启动一个Chrome浏览器实例。
  2. 新建页面: 使用browser.newPage()新建一个页面。
  3. 跳转到商品页面: 使用page.goto(url)跳转到指定的商品页面。
  4. 等待价格元素加载: 使用page.waitForSelector('.price')等待价格元素加载完成。这很重要,可以避免因页面加载延迟导致抓取失败。
  5. 获取价格文本: 使用page.$eval('.price', el => el.innerText)获取价格元素的文本内容。$eval方法会在指定的选择器找到的元素上执行一个函数,这里我们使用el => el.innerText获取元素的文本内容。
  6. 关闭浏览器: 使用browser.close()关闭浏览器实例,释放资源。
  7. 返回价格: 将抓取到的价格文本返回。

进阶:数据存储与价格比较

仅仅抓取价格还不够,我们需要将价格数据存储起来,并进行比较,才能知道价格是否发生了变化。这里我们使用JSON文件存储价格数据,你可以根据自己的需求选择其他数据库,如MySQL、MongoDB等。

const fs = require('fs');

// 数据存储文件
const dataFile = 'price_data.json';

async function monitorPrice(url) {
  const price = await getPrice(url);

  // 读取历史数据
  let data = {};
  try {
    const fileContent = fs.readFileSync(dataFile, 'utf-8');
    data = JSON.parse(fileContent);
  } catch (error) {
    // 文件不存在,忽略错误
  }

  const lastPrice = data[url];

  if (lastPrice && price !== lastPrice) {
    console.log(`价格变动!商品:${url},原价:${lastPrice},现价:${price}`);
    // 在这里可以添加告警逻辑,例如发送邮件、短信等
  } else {
    console.log(`价格未变动。商品:${url},价格:${price}`);
  }

  // 更新数据
  data[url] = price;
  fs.writeFileSync(dataFile, JSON.stringify(data, null, 2));
}

// 监控频率(毫秒)
const interval = 60 * 60 * 1000; // 1小时

// 定时执行监控任务
setInterval(() => {
  monitorPrice(productUrl);
}, interval);

这段代码做了这些事情:

  1. 读取历史数据: 从JSON文件中读取历史价格数据。如果文件不存在,则创建一个空对象。
  2. 比较价格: 将当前价格与历史价格进行比较,如果价格发生了变化,则输出价格变动信息,并可以添加告警逻辑,例如发送邮件、短信等。
  3. 更新数据: 将当前价格更新到JSON文件中。
  4. 定时执行: 使用setInterval函数,定时执行监控任务。这里我们设置监控频率为1小时,你可以根据自己的需求调整监控频率。

异常处理

在实际应用中,可能会遇到各种各样的异常情况,例如网络错误、页面结构变化等。为了保证监控系统的稳定性,我们需要对这些异常情况进行处理。

async function getPrice(url) {
  try {
    const browser = await chromium.launch();
    const page = await browser.newPage();
    await page.goto(url);
    await page.waitForSelector('.price', { timeout: 10000 }); // 设置超时时间
    const price = await page.$eval('.price', el => el.innerText);
    await browser.close();
    return price;
  } catch (error) {
    console.error(`抓取${url}价格失败:`, error);
    return null; // 返回null表示抓取失败
  }
}

async function monitorPrice(url) {
  const price = await getPrice(url);

  if (price === null) {
    console.log(`跳过${url},抓取价格失败`);
    return;
  }

  // ... 剩余代码
}

这里我们做了两点改进:

  1. 添加超时时间:page.waitForSelector方法中,我们添加了timeout选项,设置超时时间为10秒。如果10秒内价格元素没有加载完成,则会抛出一个异常。
  2. 捕获异常: 使用try...catch语句捕获可能出现的异常,并在catch块中输出错误信息。如果抓取价格失败,则返回null,并在monitorPrice函数中跳过该商品。

告警机制

当价格发生变动时,我们需要及时收到通知。这里我们使用nodemailer发送邮件告警。首先,你需要安装nodemailer:

npm install nodemailer

然后,修改monitorPrice函数,添加邮件告警逻辑:

const nodemailer = require('nodemailer');

// 邮件配置
const mailConfig = {
  host: 'smtp.example.com',
  port: 465,
  secure: true, // 使用 SSL
  auth: {
    user: 'your_email@example.com',
    pass: 'your_email_password'
  }
};

// 创建邮件发送器
const transporter = nodemailer.createTransport(mailConfig);

async function sendEmail(subject, content) {
  const mailOptions = {
    from: 'your_email@example.com',
    to: 'recipient_email@example.com',
    subject: subject,
    text: content
  };

  try {
    await transporter.sendMail(mailOptions);
    console.log('邮件发送成功');
  } catch (error) {
    console.error('邮件发送失败:', error);
  }
}

async function monitorPrice(url) {
  const price = await getPrice(url);

  if (price === null) {
    console.log(`跳过${url},抓取价格失败`);
    return;
  }

  // 读取历史数据
  let data = {};
  try {
    const fileContent = fs.readFileSync(dataFile, 'utf-8');
    data = JSON.parse(fileContent);
  } catch (error) {
    // 文件不存在,忽略错误
  }

  const lastPrice = data[url];

  if (lastPrice && price !== lastPrice) {
    const subject = `价格变动!商品:${url}`;
    const content = `商品:${url},原价:${lastPrice},现价:${price}`;
    console.log(content);
    await sendEmail(subject, content);
  } else {
    console.log(`价格未变动。商品:${url},价格:${price}`);
  }

  // 更新数据
  data[url] = price;
  fs.writeFileSync(dataFile, JSON.stringify(data, null, 2));
}

你需要替换mailConfig中的邮箱配置信息,包括SMTP服务器地址、端口、用户名和密码。然后,在价格发生变动时,就会收到邮件告警。

更上一层楼:数据可视化

为了更直观地了解价格变动情况,我们可以将价格数据可视化。这里我们使用Chart.js绘制价格趋势图。首先,你需要安装Chart.js:

npm install chart.js

然后,创建一个HTML文件,用于显示价格趋势图:

<!DOCTYPE html>
<html>
<head>
  <title>价格趋势图</title>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
  <canvas id="priceChart"></canvas>
  <script>
    // 从JSON文件读取价格数据
    async function loadData() {
      const response = await fetch('price_data.json');
      const data = await response.json();

      // 准备数据
      const labels = Object.keys(data);
      const prices = Object.values(data);

      // 创建图表
      const ctx = document.getElementById('priceChart').getContext('2d');
      const chart = new Chart(ctx, {
        type: 'line',
        data: {
          labels: labels,
          datasets: [{
            label: '价格',
            data: prices,
            borderColor: 'rgb(75, 192, 192)',
            tension: 0.1
          }]
        },
        options: {
          scales: {
            y: {
              beginAtZero: true
            }
          }
        }
      });
    }

    loadData();
  </script>
</body>
</html>

这段代码会从price_data.json文件中读取价格数据,并使用Chart.js绘制一个折线图,显示价格趋势。你需要将price_data.json文件放在与HTML文件相同的目录下,并在浏览器中打开HTML文件,即可看到价格趋势图。

总结

通过以上步骤,我们就搭建了一个简单的电商价格监控系统。你可以根据自己的需求,对系统进行扩展和完善,例如:

  • 支持更多电商网站: 修改代码,适配不同的电商网站的页面结构。
  • 支持更多商品: 将商品URL存储到数据库中,批量监控多个商品。
  • 更智能的告警: 设置更灵活的告警规则,例如价格跌幅超过一定比例时才发送告警。
  • 更丰富的数据可视化: 绘制更丰富的数据可视化图表,例如价格分布图、价格波动幅度图等。

希望这篇文章能帮助你搭建自己的电商价格监控系统,提高工作效率,更好地掌握市场动态!记住,自动化才是王道!别再傻傻地手动刷价格啦!

点评评价

captcha
健康