Puppeteer 无头 Chrome 自动化

Puppeteer 是 Google 推出的 Node.js 库,提供了一套高级 API 来操控 Chrome 或 Chromium 浏览器。它可以在无头模式(Headless)下运行,非常适合在搬瓦工 VPS 上执行网页截图、PDF 生成、自动化测试和数据抓取等任务。Puppeteer 直接通过 DevTools Protocol 与浏览器通信,性能优异且功能丰富。

一、系统要求

  • 操作系统:Ubuntu 20.04+(推荐 Ubuntu 22.04)。
  • 内存:至少 1GB,推荐 2GB 以上。
  • Node.js:16.0 以上版本。

二、安装 Node.js

apt update && apt upgrade -y
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install nodejs -y
node --version
npm --version

三、安装 Puppeteer

3.1 创建项目

mkdir -p /opt/puppeteer-project && cd /opt/puppeteer-project
npm init -y

3.2 安装 Puppeteer 及依赖

# 安装 Puppeteer(自带 Chromium)
npm install puppeteer

# 安装系统依赖
apt install -y libx11-xcb1 libxcomposite1 libxcursor1 libxdamage1 \
  libxi6 libxtst6 libnss3 libcups2 libxss1 libxrandr2 \
  libasound2 libpangocairo-1.0-0 libatk1.0-0 libatk-bridge2.0-0 \
  libgtk-3-0 libgbm1 libdrm2

如果不想下载内置 Chromium,可以使用 puppeteer-core 并指定系统 Chrome 路径:

npm install puppeteer-core

四、基础用法

4.1 网页截图

创建 screenshot.js 文件:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: 'new',
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  });

  const page = await browser.newPage();
  await page.setViewport({ width: 1920, height: 1080 });
  await page.goto('https://example.com', { waitUntil: 'networkidle2' });
  await page.screenshot({ path: 'screenshot.png', fullPage: true });

  console.log('截图已保存');
  await browser.close();
})();

运行脚本:

node screenshot.js

4.2 生成 PDF

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: 'new',
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  });

  const page = await browser.newPage();
  await page.goto('https://example.com', { waitUntil: 'networkidle2' });

  await page.pdf({
    path: 'output.pdf',
    format: 'A4',
    margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' },
    printBackground: true
  });

  console.log('PDF 已生成');
  await browser.close();
})();

4.3 表单操作与页面交互

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: 'new',
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  });

  const page = await browser.newPage();
  await page.goto('https://example.com/login');

  // 输入用户名和密码
  await page.type('#username', 'myuser', { delay: 50 });
  await page.type('#password', 'mypassword', { delay: 50 });

  // 点击登录按钮并等待导航
  await Promise.all([
    page.waitForNavigation({ waitUntil: 'networkidle2' }),
    page.click('#login-btn')
  ]);

  console.log('登录后 URL:', page.url());
  await browser.close();
})();

五、数据提取

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: 'new',
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  });

  const page = await browser.newPage();
  await page.goto('https://example.com');

  // 提取页面数据
  const data = await page.evaluate(() => {
    const items = [];
    document.querySelectorAll('.item').forEach(el => {
      items.push({
        title: el.querySelector('h2')?.textContent?.trim(),
        link: el.querySelector('a')?.href,
        price: el.querySelector('.price')?.textContent?.trim()
      });
    });
    return items;
  });

  console.log(JSON.stringify(data, null, 2));
  await browser.close();
})();

六、请求拦截

通过请求拦截可以屏蔽不必要的资源加载,提升页面打开速度:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: 'new',
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  });

  const page = await browser.newPage();

  // 启用请求拦截
  await page.setRequestInterception(true);
  page.on('request', (req) => {
    const resourceType = req.resourceType();
    if (['image', 'font', 'stylesheet'].includes(resourceType)) {
      req.abort();
    } else {
      req.continue();
    }
  });

  await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
  const title = await page.title();
  console.log('页面标题:', title);
  await browser.close();
})();

七、多页面并发处理

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    headless: 'new',
    args: ['--no-sandbox', '--disable-setuid-sandbox']
  });

  const urls = [
    'https://example.com/page1',
    'https://example.com/page2',
    'https://example.com/page3',
  ];

  const results = await Promise.all(urls.map(async (url) => {
    const page = await browser.newPage();
    await page.goto(url, { waitUntil: 'networkidle2' });
    const title = await page.title();
    await page.close();
    return { url, title };
  }));

  console.log(results);
  await browser.close();
})();

八、性能优化

在搬瓦工 VPS 上运行 Puppeteer,建议进行以下优化:

const browser = await puppeteer.launch({
  headless: 'new',
  args: [
    '--no-sandbox',
    '--disable-setuid-sandbox',
    '--disable-dev-shm-usage',       // 避免 /dev/shm 空间不足
    '--disable-accelerated-2d-canvas', // 禁用 GPU 加速
    '--disable-gpu',                   // 禁用 GPU
    '--single-process',                // 单进程模式(低内存)
    '--no-zygote',                     // 禁用 zygote 进程
    '--js-flags=--max-old-space-size=256' // 限制内存
  ]
});

九、定时任务

将 Puppeteer 脚本配置为定时任务:

crontab -e

# 每小时执行一次截图任务
0 * * * * cd /opt/puppeteer-project && /usr/bin/node screenshot.js >> /var/log/puppeteer.log 2>&1

也可以使用 systemd 管理服务化的 Puppeteer 应用:

cat > /etc/systemd/system/puppeteer-app.service <<EOF
[Unit]
Description=Puppeteer Application
After=network.target

[Service]
Type=simple
User=root
WorkingDirectory=/opt/puppeteer-project
ExecStart=/usr/bin/node app.js
Restart=on-failure
RestartSec=10
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable puppeteer-app
systemctl start puppeteer-app

十、常见问题

Chromium 启动报错

VPS 上缺少图形库依赖是最常见的问题,确保已安装所有必要的系统包。也可以查看具体报错:

ldd $(find /opt/puppeteer-project/node_modules -name chrome -type f) | grep "not found"

超时错误

增加页面加载超时时间:

await page.goto('https://example.com', {
  waitUntil: 'networkidle2',
  timeout: 60000  // 60 秒
});

总结

Puppeteer 是在搬瓦工 VPS 上进行浏览器自动化的优秀选择,适用于截图监控、PDF 生成、自动化测试和数据采集等场景。建议选择内存 2GB 以上的方案。选购搬瓦工 VPS 请参考 全部方案,购买时使用优惠码 NODESEEK2026 可享受 6.77% 折扣。相关教程:Playwright 教程Selenium 教程

关于本站

搬瓦工VPS中文网(bwgvps.com)是非官方中文信息站,整理搬瓦工的方案、优惠和教程。我们不销售主机,不提供技术服务。

新手必读
搬瓦工优惠码

NODESEEK2026(优惠 6.77%)

购买时填入即可抵扣。