admin管理员组

文章数量:1180431

If I have this code:

const puppeteer = require('puppeteer');

var test = async () => {
  const browser = await puppeteer.launch({args: ["--no-sandbox", "--disable-setuid-sandbox"]});
  const page = await browser.newPage();
  await page.goto(':WikiActivity');
  let element =  await page.$('#WikiaMainContent');
  await page.setViewport({ width: 800, height: 1000}); // This is ignored
  await element.screenshot({path: "./wiki.png"});
  await browser.close(); 
}

test();

The screenshot is larger than the viewport.

How can I make it so that the screenshot has a width of 800px and height of 1000px?

If I have this code:

const puppeteer = require('puppeteer');

var test = async () => {
  const browser = await puppeteer.launch({args: ["--no-sandbox", "--disable-setuid-sandbox"]});
  const page = await browser.newPage();
  await page.goto('https://community.wikia.com/wiki/Special:WikiActivity');
  let element =  await page.$('#WikiaMainContent');
  await page.setViewport({ width: 800, height: 1000}); // This is ignored
  await element.screenshot({path: "./wiki.png"});
  await browser.close(); 
}

test();

The screenshot is larger than the viewport.

How can I make it so that the screenshot has a width of 800px and height of 1000px?

Share Improve this question edited Sep 30, 2018 at 23:52 Grant Miller 29k16 gold badges155 silver badges168 bronze badges asked Sep 29, 2018 at 22:36 Jamie AdamsJamie Adams 3071 gold badge3 silver badges11 bronze badges 3
  • Sorry, I wrote this code from memory, please check the edit. – Jamie Adams Commented Sep 30, 2018 at 1:25
  • In the corrected code, you do not call a main IIFE-function? – stdob-- Commented Sep 30, 2018 at 2:05
  • I've tested this one properly now. It generates a new image, but it is still too large – Jamie Adams Commented Sep 30, 2018 at 2:56
Add a comment  | 

3 Answers 3

Reset to default 31

You can use the clip option of elementHandle.screenshot() in conjunction with elementHandle.boundingBox() to set the width and height of an element screenshot.

The example below will take a screenshot of an element, and clip the element if it exceeds the current viewport:

await page.setViewport({
  width: 800,
  height: 1000,
});

const example = await page.$('#example');
const bounding_box = await example.boundingBox();

await example.screenshot({
  path: 'example.png',
  clip: {
    x: bounding_box.x,
    y: bounding_box.y,
    width: Math.min(bounding_box.width, page.viewport().width),
    height: Math.min(bounding_box.height, page.viewport().height),
  },
});

I have a better solution using html2canvas in the front:

https://gist.github.com/homam/3162383c8b22e7af691085e77cdbb414

or using it with puppeteer and html2canvas in the Backend:

const screenshot = await page.evaluate(async () => {
   const canvasElement = await html2canvas($("div")[0], {
        // useCORS: true,
   });

   let image = Canvas2Image.convertToImage(
        canvasElement,
        $(canvasElement).width(),
        $(canvasElement).height(),
        "png"
    );
    console.log(image.src)
    return image.src;
})
var fs = require('fs');
// strip off the data: url prefix to get just the base64-encoded bytes
var data = screenshot.replace(/^data:image\/\w+;base64,/, "");
var buf = new Buffer(data, 'base64');
fs.writeFile(`./screenshots/div-${Date.now()}-.png`, buf);

full code here: https://github.com/davidtorroija/screenshot-of-div-e2e/blob/master/README.md

this is better because is easy to take a screenshot of a huge div, and no need to scroll, and you are not going to lose any part of the div

Lauching puppeteer with defaultViewport, worked for me:

await puppeteer.launch({ headless: 'new', defaultViewport: { width: 1920, height: 1080 } })

本文标签: javascriptSet Width and Height of Element Screenshot in PuppeteerStack Overflow