0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Puppeteerで16384pxを超える巨大なスクリーンショットを撮影する方法

Last updated at Posted at 2024-10-03

巨大なスクリーンショットの撮影に失敗する問題を解決した

Puppeteerでは縦横いずれかが16384pxを超えるスクリーンショットを撮影できない。
これはChromiumの仕様によるものだ。
高さのあるサイトのスクリーンショットを撮ろうとすると画像の左のように、上部が繰り返されてしまう。
GitHubにイシューとして報告されており、問題が部分的に放置されたままcloseとなっていた。
そこで画像の右のように、下までちゃんとスクリーンショットが撮影できるようなコードを作成した。

369992439-7b7e717f-14d2-4c94-969a-f3b637123429.png

解決策

次に示すコードにあるtakeFullPageScreenshot関数を呼び出し、page.screenshotの代わりに使う。

// Before
  const defaultScreenshot = await page.screenshot({
    fullPage: true,
  });

// After
  const screenshot = await takeFullPageScreenshot(page); // here!

takeFullPageScreenshotはこちら。

軽く説明すると、細かく画像を分割してスクリーンショットを撮影し、最後に結合することで、16384pxのリミットを超えないようにしている。

使用例

import fs from "fs";
import puppeteer from "puppeteer";

import takeFullPageScreenshot from "./index";

const url =
  "https://nextjs.org/docs/app/building-your-application/routing/route-handlers";
const width = 1500;
const deviceScaleFactor = 2;

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

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

  await page.setViewport({
    width: width,
    height: 500,
    deviceScaleFactor,
  });

  await new Promise((resolve) => setTimeout(resolve, 500));

  const screenshot = await takeFullPageScreenshot(page); // here!

  browser.close();
  fs.writeFileSync("./results/screenshot.png", screenshot);
})();

残りの問題

sharpというjavascriptの画像編集ライブラリを用いている。sharpに画像サイズのハードリミットが設定されているようで、これを超えると失敗する。
そうそう超えることはないだろうが、deviceScaleFactorを大きくするとリミットを超えて失敗することある。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?