【问题标题】:Using Spatie's Browsershot/Headless Chrome to capture extremely long screenshots使用 Spatie 的 Browsershot/Headless Chrome 捕捉超长截图
【发布时间】:2018-07-01 17:13:50
【问题描述】:
我会定期遇到需要使用 Spatie 的 Browsershot 来捕获非常高的网页的情况。但是,当我这样做时,生成的屏幕截图每 16,384 像素重复一次。 (你可以在这里看到一个重复的例子:https://github.com/GoogleChrome/puppeteer/issues/1576)
这是 Puppeteer 的一个已知限制(记录在 here)。目前推荐的解决方法似乎是截取几张屏幕截图,并使用clip() 将屏幕截图偏移 16,384 像素。您可以查看使用 Node.js here 的这种方法的示例。
现在,在客户端,这种方法似乎工作得很好,但在 Browsershot 库的上下文中这并不能真正帮助我们。据我所知,在 PHP 中没有可行的方法来获取页面的高度。谁能想到服务器端的任何潜在解决方法来破解一个极长的屏幕截图?
我知道这并不是图书馆的真正预期用途,归根结底,这甚至不是图书馆的限制,但我想我还是把它扔在那里。
【问题讨论】:
标签:
javascript
php
laravel
google-chrome-headless
【解决方案1】:
通过对 Spatie 的 Browsershot 的新贡献,您可以使用您提供的 example 中的方法轻松捕获非常高的网页。
$url = 'http://www.spiegel.de';
//Get scrollWidth and scrollHeight of the body in the emulated device
$browsershot = new Browsershot($url, true);
$dimensions = $browsershot
->device('iPhone 6')
->waitUntilNetworkIdle() // ensuring all additional resources are loaded
->evaluate("JSON.stringify({height: document.body.scrollHeight, width: document.body.scrollWidth})");
$dimensions = json_decode($dimensions);
// iphone 6 scale factor is equal to 2
// https://github.com/GoogleChrome/puppeteer/blob/master/DeviceDescriptors.js#L288
$dpr = 2;
$maxScreenshotHeight = floor(16 * 1024 / $dpr);
for ($ypos = 0; $ypos < $dimensions->height; $ypos += $maxScreenshotHeight) {
$height = min($dimensions->height - $ypos, $maxScreenshotHeight);
$browsershot = new Browsershot($url, true);
$browsershot
->device('iPhone 6')
->waitUntilNetworkIdle()
->clip(0, $ypos, $dimensions->width, $height)
->timeout(120000) // handling timeout
->save('screenshot-@' . $ypos . 'px.png');
}