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

如何解决Puppeteer(Node.js)截取动态网站截图失真问题?

Puppeteer在Docker中截取动态网站截图失真的解决建议

问题背景

使用Puppeteer(版本^2.0.0)在Docker容器中执行网页截图操作,静态网站的完整截图可正常生成,但截取https://www.schoox.com/、https://www.cyclopt.com/这类含动态内容的网站时,截图严重失真。即使注释自动滚动函数,问题仍存在。

相关代码

const puppeteer = require('puppeteer')

const config = {
  launchOptions: {
    headless: false,
    args: [
        // Required for Docker version of Puppeteer
        '--no-sandbox',
        '--disable-setuid-sandbox',
        // This will write shared memory files into /tmp instead of /dev/shm,
        // because Docker’s default for /dev/shm is 64MB
        '--disable-dev-shm-usage',
        // load browser extensions
        `--disable-extensions-except=${cookieIgnorePath}`,
        `--load-extension=${cookieIgnorePath}`,
      ]
  },
  viewport: {
    width: 1366, 
    height: 1600
  }
}


function processInputUrl(url) {
  url = url.trim()

  if (!(url.toLowerCase().search('http:') === 0 || url.toLowerCase().search('https:') === 0)) {
    url = "http://".concat(url)
  }

  // ToDO: add protection against XSS

  return url

}

async function getWebpageImage(url, imagePath) {

  return puppeteer.launch(config.launchOptions)
    .then(async browser => {

      let succeeded = true

      try {
        const page = await browser.newPage()

        await page.setViewport(config.viewport)

        await page.goto(url, {"waitUntil": "networkidle0"})

        // auto scroll to the bottom of the page
        await autoScroll(page);
    
        // hide scrollbar 
        await page.evaluate(() => { 
          document.querySelector('html').style.overflow = 'hidden'
        }) 

        // let source = await page.content()

        await page.screenshot({ path: imagePath, fullPage: true})
      }

      catch(err) {
        console.log('Website cannot be reached')
        console.log(err)

        succeeded = false
      }

      await browser.close()

      return succeeded
    })
}


// Function to scroll to the bottom of the page
async function autoScroll(page) {
  await page.evaluate(async () => {
    await new Promise((resolve, reject) => {
      let totalHeight = 0;
      const distance = 100;
      const maxScrollAttempts = 50;

      const timer = setInterval(() => {
        const scrollHeight = document.body.scrollHeight;
        window.scrollBy(0, distance);
        totalHeight += distance;

        // If scrolled to the bottom of the page or reached max scroll attempts
        if (totalHeight >= scrollHeight || maxScrollAttempts <= 0) {
          clearInterval(timer);
          resolve();
        }
        maxScrollAttempts--;
      }, 100); // scroll speed
    });
  });
}

解决建议

  • 调整页面等待策略:networkidle0可能过早结束等待,导致动态内容未渲染完成。换成networkidle2,或结合waitForSelector等待关键动态元素加载:
    await page.goto(url, {waitUntil: 'networkidle2'});
    // 按需修改选择器,等待主内容区加载
    await page.waitForSelector('main', {timeout: 10000});
    
  • 修正无头模式配置:Docker环境下headless: false易引发渲染异常,切换为headless: 'new'(Puppeteer v2+支持)或headless: true,并补充渲染优化参数:
    launchOptions: {
      headless: 'new',
      args: [
        '--no-sandbox',
        '--disable-setuid-sandbox',
        '--disable-dev-shm-usage',
        '--disable-extensions-except=' + cookieIgnorePath,
        '--load-extension=' + cookieIgnorePath,
        '--start-maximized',
        '--disable-web-security',
        '--disable-features=VizDisplayCompositor'
      ]
    }
    
  • 增加截图前延迟:给动态内容足够渲染时间,可根据网站情况调整时长:
    await page.waitForTimeout(2000);
    
  • 修复自动滚动逻辑:原函数中maxScrollAttempts递减逻辑错误,修正后确保循环计数正确:
    async function autoScroll(page) {
      await page.evaluate(async () => {
        await new Promise((resolve) => {
          let totalHeight = 0;
          const distance = 100;
          let attempts = 50;
          const timer = setInterval(() => {
            const scrollHeight = document.body.scrollHeight;
            window.scrollBy(0, distance);
            totalHeight += distance;
            attempts--;
            if (totalHeight >= scrollHeight || attempts <= 0) {
              clearInterval(timer);
              resolve();
            }
          }, 100);
        });
      });
    }
    
  • 排查扩展干扰:暂时注释加载扩展的代码,确认是否是扩展导致渲染异常:
    // '--disable-extensions-except=' + cookieIgnorePath,
    // '--load-extension=' + cookieIgnorePath,
    
  • 检查Docker镜像依赖:使用官方puppeteer/puppeteer镜像,或在自定义镜像中安装libx11-xcb1、libxcomposite1、libxcursor1等Chrome必要依赖。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 21:54:55