Puppeteer:屏幕截图惰性图像不起作用[重复]

2024-03-07

我似乎无法捕获屏幕截图https://today.line.me/HK/pc https://today.line.me/HK/pc成功地。

在我的 Puppeteer 脚本中,我还启动了滚动到页面底部并再次向上滚动以确保加载图像。但由于某种原因,它似乎不适用于上面的 URL 行。

function wait (ms) {
 return new Promise(resolve => setTimeout(() => resolve(), ms));
}

const puppeteer = require('puppeteer');

async function run() {
let browser = await puppeteer.launch({headless: false});
let page = await browser.newPage();
await page.goto('https://today.line.me/HK/pc', {waitUntil: 'load'});
//https://today.line.me/HK/pc
// Get the height of the rendered page
  const bodyHandle = await page.$('body');
  const { height } = await bodyHandle.boundingBox();
  await bodyHandle.dispose();

  // Scroll one viewport at a time, pausing to let content load
  const viewportHeight = page.viewport().height+200;
  let viewportIncr = 0;
  while (viewportIncr + viewportHeight < height) {
    await page.evaluate(_viewportHeight => {
      window.scrollBy(0, _viewportHeight);
    }, viewportHeight);
    await wait(4000);
    viewportIncr = viewportIncr + viewportHeight;
  }

  // Scroll back to top
  await page.evaluate(_ => {
    window.scrollTo(0, 0);

  });

 // Some extra delay to let images load
 await wait(2000);

await page.setViewport({ width: 1366, height: 768});
await page.screenshot({ path: './image.png', fullPage: true });
}

run();

对于任何想知道的人来说,有很多策略可以在 Puppeteer 中渲染延迟加载的图像或资源,但并非所有策略都同样有效。您尝试截屏的网站中的小实现细节可能会改变最终结果,因此,如果您希望实现能够在多种案例场景中正常运行,您将需要隔离每个通用案例并单独解决。

我知道这一点是因为我经营一家小型公司截图API https://www.getscreenshotapi.com服务人员和我必须单独处理许多案件。这是该项目的一项艰巨任务,因为似乎总是有新的问题需要通过每天使用的新库和 UI 技术来解决。

话虽这么说,我认为有一些渲染策略具有良好的覆盖范围。也许最好的方法是像OP那样将等待和滚动页面结合起来,但也要确保考虑到操作的顺序。这是 OP 原始代码的稍微修改版本。

//Scroll and Wait Strategy

function waitFor (ms) {
  return new Promise(resolve => setTimeout(() => resolve(), ms));
}

async function capturePage(browser, url) {
  // Load the page that you're trying to screenshot.
  const page = await browser.newPage();
  await page.goto(url, {waitUntil: 'load'}); // Wait until networkidle2 could work better.


  // Set the viewport before scrolling
  await page.setViewport({ width: 1366, height: 768});

  // Get the height of the page after navigating to it.
  // This strategy to calculate height doesn't work always though. 
  const bodyHandle = await page.$('body');
  const { height } = await bodyHandle.boundingBox();
  await bodyHandle.dispose();

  // Scroll viewport by viewport, allow the content to load
  const calculatedVh = page.viewport().height;
  let vhIncrease = 0;
  while (vhIncrease + calculatedVh < height) {
    // Here we pass the calculated viewport height to the context
    // of the page and we scroll by that amount
    await page.evaluate(_calculatedVh => {
      window.scrollBy(0, _calculatedVh);
    }, calculatedVh);
    await waitFor(300);
    vhIncrease = vhIncrease + calculatedVh;
  }

  // Setting the viewport to the full height might reveal extra elements
  await page.setViewport({ width: 1366, height: calculatedVh});

  // Wait for a little bit more
  await waitFor(1000);

  // Scroll back to the top of the page by using evaluate again.
  await page.evaluate(_ => {
    window.scrollTo(0, 0);
  });

  return await page.screenshot({type: 'png'});
}

这里的一些主要区别是:

  • 您希望从一开始就设置视口并使用该固定视口进行操作。

  • 您可以更改等待时间并引入任意等待来进行实验。有时,这会导致网络事件背后的元素被揭露。

  • 将视口更改为页面的完整高度也可以显示元素,就像滚动一样。您可以使用垂直显示器在真实的浏览器中进行测试。但是,请确保返回到原始视口高度,因为视口也会影响预期的渲染。

这里需要理解的一件事是,单独等待并不一定会触发惰性资产的加载。滚动文档的高度允许视口显示那些需要在视口内加载的元素。

另一个需要注意的是,有时您需要等待相对较长的时间才能加载资源,因此在上面的示例中,您可能需要尝试每次滚动后等待的时间量。另外,正如我提到的,一般执行中的任意等待有时会影响资产是否加载。

一般来说,当使用 Puppeteer 进行屏幕截图时,您需要确保您的逻辑类似于真实的用户行为。您的目标是重现渲染场景,就好像有人在计算机中启动 Chrome 并导航到该网站一样。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Puppeteer:屏幕截图惰性图像不起作用[重复] 的相关文章

  • Puppeteer:Element.hover() 不存在

    我正在使用 puppeteer 从网站上抓取一些图像以及其他一些数据 要更改图像 我需要将鼠标悬停在列表项上 我不断遇到有关 hover 的文档 但没有成功 然而 click 非常适合我的抓取的另一部分 const pptr require
  • 如何检测与 puppeteer 一起使用的 chrome 版本?

    我读到 puppeteer 使用最新版本的 chrome 我在哪里可以找到它正在使用的版本 我不想访问窗口上的导航器对象来获取它 基本上没有什么运行时 只是想知道 puppeteer 作为一个包是否在某处列出了它的依赖项 基本上 我想从其他
  • 如何在 puppeteer 中传递实验性 chrome 选项

    我有一个用 python 编写的应用程序selenium https www selenium dev 其中设置了一些实验选项镀铬驱动程序 https chromedriver chromium org from selenium impo
  • 如何使用 Puppeteer 登录 Google?

    我正在使用 Puppeteer 并且正在尝试登录我的 Gmail 帐户 URL 目前我的代码输入电子邮件表单并提交输入 然后当页面进入密码屏幕时 无法输入密码 这可能是因为它在技术上不是新页面 而是相同的 不管怎样 当我在电子邮件页面上按
  • Puppeteer 启动器错误结果未定义

    在 Windows 上测试我的项目后 我将其部署到基于 Ubuntu 的虚拟机上 这就是 Puppeteer 行为让我感到困惑的地方 我确实安装了所有必需的依赖项 但我有一种感觉 我的错误不一定是由于缺乏依赖项以及更多有关配置问题而引起的
  • waitForSelector 找不到相关部分

    我使用以下代码与 Puppeteer 来检查相关部分是否已加载 但它总是返回加载错误 这可能是什么原因 缺少哪一部分我不明白 我正在使用下面的代码 async function getResults lnk const results co
  • 如何让puppeteer浏览器保持在后台运行而不跳转到前台?

    使用时puppeteer通过a抓取一堆网站for loop 每当创建一个新页面时 浏览器就会跳转到前台 这妨碍了我在计算机上做其他事情 即使我设置了以下参数 它仍然不起作用 那么我怎样才能让浏览器安静地运行而不跳到前台并打断我呢 我需要跑进
  • 如何避免“框架分离”错误异步验证或使用 Puppeteer 进行重定向?

    以前的一个answer https stackoverflow com questions 51066987 puppeteer how can i wait for ajax request and process the result为
  • Node.js 中的活动句柄是什么

    我发现我的应用程序活动句柄数不断增加 活动句柄的数量究竟是多少 这是我必须注意防止应用程序崩溃的事情吗 活动手柄 句柄是对开放资源 例如打开的文件 数据库连接或请求 的引用 为了理解为什么句柄应该处于关闭状态却可能处于活动状态 我给你一个简
  • puppeteer 通过启用 cookie 和 Javascript 绕过 cloudflare

    仅在 NodeJs gt 服务器端 我正在做一些网页抓取 一些页面受到 cloudflare anti ddos 页面的保护 我正在尝试绕过此页面 通过搜索 我发现了很多关于隐身方法或 reCapcha 的文章 但问题是 cloudflar
  • 将 puppeteer 与 headless_shell 一起使用

    我在用 https www npmjs com package puppeteer pdf https www npmjs com package puppeteer pdf其中有 puppeteer 作为依赖项 Heroku 对我 gt
  • puppeteer 无法在浏览器中加载 chrome 扩展

    这是我第一次使用 puppeteer 我想打开 google chrome 页面并导航到我已安装的 chrome 扩展 我尝试启用 chrome 扩展 但是当我在中运行脚本时headless false模式下浏览器会弹出 没有我的扩展程序
  • Puppeteer pdf 分页错误

    我尝试用 puppetter 生成 pdf 文件 它适用于一页 但当我尝试生成多页 pdf 文档时 我遇到了分页错误 下面使用 HTML 模板来生成 如果可以 请你帮助我 复制的前提条件 将第一页填充到 100 高度并为下面的块添加标题 H
  • 继续处理结果的 Null 值(Nodejs、Puppeteer)

    我刚刚开始使用 Puppeteer Headless Chrome 和 Nodejs 我正在抓取一些测试站点 当所有值都存在时 一切都很好 但如果该值丢失 我会收到如下错误 Cannot read property src of null
  • Schmooze:: 使用 grover gem 转换 html2pdf 时处理失败+

    respond to do format format html format pdf do grover Grover new http localhost 3000 generate report format A4 pdf grove
  • page.goto() 上的云函数超时

    我在云函数中使用 puppeteer 运行测试 如果我在本地机器上运行测试一切都很好 如果我在云函数模拟器中运行测试也没关系 但是当我将函数部署到云端时 所有测试都停留在 page goto https 并且函数因超时而失败 在我的例子中是
  • 弹出表单可见,但 Puppeteer 中缺少 html 代码

    我目前正在尝试从网站获取一些信息 https www bauhaus info https www bauhaus info 并在 cookie 弹出表单中失败 到目前为止 这是我的代码 async gt const browser awa
  • Puppeteer 无法在 VPS (DigitalOcean) 上工作

    我在水滴中数字海洋 https www digitalocean com 我收到这个错误 node 5549 UnhandledPromiseRejectionWarning TimeoutError Navigation Timeout
  • 消息“在 jest.setTimeout 指定的 5000 毫秒超时内未调用异步回调”

    我正在使用 Puppeteer 和 Jest 来运行一些前端测试 我的测试如下 describe Profile Tab Exists and Clickable settings user gt test Assert that you
  • 通过 DevTools 协议从 Chromium 进行“向外”通信

    我有一个页面在无头 Chromium 实例中运行 我通过 DevTools 协议使用 Node js 中的 Puppeteer NPM 包来操作它 我正在将脚本注入到页面中 在某些时候 我希望脚本给我回电并向我发送一些信息 通过 DevTo

随机推荐