LoginSignup
30
23

More than 5 years have passed since last update.

puppeteerでスクショを撮る時に調べた4つのこと

Posted at

背景

※ここは読み飛ばしていただいて大丈夫です。

WinActorというツールをご存知でしょうか。
RPA(ロボティック・プロセス・オートメーション)ツールとして、とても便利な良いツール(らしい)です。

ただ、買うと高いです。
年間で諭吉が100人とか飛んでいくレベルです。

さてさて、このツールですが、たまたま私が属している会社は購入していました。
そこで、とあるウェブサイトのスクショを撮りたいという要望があり、WinActorが使えないかという話が出ていたので試したわけです。

なるほど、ふむふむと説明資料を読み込みながら思いました。

「puppeteerで良いのでは?」

もちろん、今回の件に関してはpuppetterで出来そうだったというだけで、
puppetterの方が優れているとかいうつもりはありません

WinActorの方が色々とできる幅も広そうだし、便利そうなツールだなーと思いました。
社内で使うなら、使い倒せばいいと思います。(購入しているわけですし)

ただ、調査はするものの、実際に使うのは当社じゃなかったので、
「WinActorというツールを購入していただければ、希望通りスクショを撮れそうです!諭吉100人分の予算とってください!あ、毎年かかります!」
とは言いにくいです。

いえね、費用対効果的に元が取れるなら良いと思いますし、他の業務でWinActorを使い倒せるような余地があるなら購入した方が色々幸せになるのではと思いますよ?
今回の用途だけなら厳しいのではないかなーと思ったというだけです。

ともあれ、そういうわけで、「試しにpuppeteerだとどうなるかなー」と試した備忘録です。
スクショを撮る際に、調べてもパッと見つからなかった「個人的に知りたかったこと」を載せています。

あ、ちなみに結論から言えば、puppetterでできそうでした。

スクリーンショット

まずは普通に撮ってみます。
保存先のpathに関してはローカル環境に合わせて書き換えてください。


export class UsePuppeteer {
    private browser: Browser;

    constructor() {

        // テスト用にheadlessにせず、動作にも遅延をかける
        puppeteer.launch( {
            headless: false,
            slowMo: 10,
            args: [ "--no-sandbox", "--disable-setuid-sandbox" ]
        } )
            .then( ( browserObj ) => {
                this.browser = browserObj;
                return this.test();
            } )
            .catch( ( err ) => {
                throw err;

    }
    async test(): Promise<any> {
        const page = await this.browser.newPage();
        await page.setViewport( {
            width: 1200,
            height: 800
        } );

        await page.goto( "https://blog.qiita.com/", { waitUntil: "domcontentloaded" } );

        await page.screenshot( {
            path: "/Users/hoge/Desktop/test.png"
        } );

        await page.close();
    }
}

撮った画像は以下の通り。

test0.png

注意

以降のコードは、普通に撮った場合のコードから変更があった部分のみ載せます。

jpegで保存するようにしてスクショ


        await page.screenshot( {
            path: "/Users/hoge/Desktop/test.jpg",
            type: "jpeg",
            quality: 100
        } );

メモ

  • typeでjpegを指定しなくても、pathで指定している保存ファイル名がjpgならjpgで保存される。
  • qualityを指定しないと、たぶん80が適用される。(出力されるファイルサイズで見ただけ)
  • qualityはpngで保存しようとした時に指定していると、エラー。
    • UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Error: options.quality is unsupported for the png screenshots

fullPageをtrueでスクショ

        await page.screenshot( {
            path: "/Users/hoge/Desktop/test.png",
            fullPage: true
        } );

撮った画像は以下の通り。

test.png

プレビューのインスペクタは以下の通り。

スクリーンショット.png

メモ

  • fullPageをtrueにした場合、幅はそのままで、高さが可変になる。

PCの画面サイズを超えるサイズでスクショ

「上述のfullPageでできたのだから、もしや最初のwidthとheightの指定を変えれば、すごい大きいスクショが撮れるのでは?」
というところからスタート。
さて結果はいかに。

        await page.setViewport( {
            width: 7680,
            height: 4320
        } );

撮った画像は以下の通り。

test.png

プレビューのインスペクタは以下の通り。

スクリーンショット.png

メモ

  • PCの画面に表示しきれないサイズでもスクショできる。

特定の要素(領域)だけスクショ


        // 描画領域を取得
        const rect = await page.evaluate( () => {
            const rect = document.getElementById( "masthead" ).getBoundingClientRect();
            return {
                x: rect.left,
                y: rect.top,
                width: rect.width,
                height: rect.height
            };
        } );

        await page.screenshot( {
            path: "/Users/hoge/Desktop/test.png",
            clip: rect
        } );

撮った画像は以下の通り。

test.png

試しに、imgタグを指定するのではななく、その親のheader部分の要素のサイズに従って保存しました。

メモ

  • 特定の領域のみスクショで保存したい場合はclipを使う。
  • 特定の要素の領域をスクショで保存したい場合は、getBoundingClientRect()で取得した値を利用してどうにかすると楽。
30
23
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
30
23