Skip to content

Instantly share code, notes, and snippets.

@derFunk
Created February 26, 2018 07:54
Show Gist options
  • Save derFunk/10747ce60e965de5b771e96b7a4ba8f7 to your computer and use it in GitHub Desktop.
Save derFunk/10747ce60e965de5b771e96b7a4ba8f7 to your computer and use it in GitHub Desktop.
Long screenshots with headless chrome, avoiding the 16384 pixel count limitation (texture size)
#!/usr/bin/env node
function sleep(ms) {
ms = (ms) ? ms : 0;
return new Promise(resolve => {setTimeout(resolve, ms);});
}
process.on('uncaughtException', (error) => {
console.error(error);
process.exit(1);
});
process.on('unhandledRejection', (reason, p) => {
console.error(reason, p);
process.exit(1);
});
const puppeteer = require('puppeteer');
if (!process.argv[2]) {
console.error('ERROR: no url arg\n');
console.info('for example:\n');
console.log(' docker run --shm-size 1G --rm -v /tmp:/screenshots \\');
console.log(' alekzonder/puppeteer:latest screenshot \'https://www.google.com\'\n');
process.exit(1);
}
var url = process.argv[2];
var now = new Date();
var dateStr = now.toISOString();
var width = 800;
if (typeof process.argv[3] === 'string') {
var width = parseInt(process.argv[3], 10);
}
var delay = 0;
if (typeof process.argv[4] === 'string') {
delay = parseInt(process.argv[4], 10);
}
(async() => {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--disable-dev-shm-usage'
]
});
const page = await browser.newPage();
await page.goto(url, {
waitUntil: 'networkidle2'
});
await sleep(delay);
const {contentSize} = await page._client.send('Page.getLayoutMetrics');
const maxScreenshotHeight = Math.floor(16 * 1024); // Hardcoded max texture size of 16,384 (crbug.com/770769)
let filename = `${dateStr}_full_screenshot_${width}_${contentSize.height}`;
let files=[]
let i=0
// Inspired by https://github.com/GoogleChrome/puppeteer/blob/230be28b067b521f0577206899db01f0ca7fc0d2/examples/screenshots-longpage.js
for (let ypos = 0; ypos < contentSize.height; ypos += maxScreenshotHeight) {
const height = Math.min(contentSize.height - ypos, maxScreenshotHeight);
let thisFilename=`${filename}-${i}.png`
//dirty hack. without this reload, the screenshotting gets stuck in this loop.
// error happening: { Error: Protocol error (Page.captureScreenshot): Target closed.
// page.reload({
// waitUntil: 'networkidle2'
// })
await page.screenshot({
path: `/screenshots/${thisFilename}`,
clip: {
x: 0,
y: ypos,
width: contentSize.width,
height
}
});
files.push({
filename: thisFilename,
width: contentSize.width,
height,
ypos
});
i++;
}
browser.close();
console.log(
JSON.stringify({
date: dateStr,
timestamp: Math.floor(now.getTime() / 1000),
files,
width,
height: contentSize.height
})
)
process.exit(0);;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment