概要
- Windows, Linux版Google Chromeのヘッドレス実行でスクリーンショットを取得。
- RHEL9系Linux(AlmaLinux, MIRACLE LINUX, CentOS, RockyLinux)でBash動く説明。
- dnf(yum)あればおk
- macOSはHomebrewやらNodebrewで色々入れてある前提. 標準ターミナルのZshで動く説明。
- 各環境でスクショやHTMLでPDF帳票欲しかったのでまとめた感じです。
この記事執筆時点での確認環境[2024/11/07]
- Google Chrome 130.0.6723.117
- Windows 11 Pro 23H2(64 ビット)
- macOS 15.1 Sequoia(Mac mini[M1]で確認)
- AlmaLinux 9.4(どこぞのVPS環境)
- Node.js(npm,npx)
- npm --version 10.9.0
Chrome ヘッドレス モード
Chrome for Developers Chrome ヘッドレス モード 参照.
ヘッドレス モードは Chrome 59 以降、Mac と Linux でご利用いただけます。 Windows サポート Chrome 60 で導入されました。
Chrome 112 でヘッドレス モードが更新された
……ということで、2023/04/04にリリースされたGoogle Chrome 112系でheadlessフラグのvalue値指定無しが使えなくなっているようです。
Chrome 111以前の古いやり方
Google Chromeバイナリを直接叩く、
- 前提:Windows版Google Chromeをインストール済みであること。
cd C:\var\temp
# PNG形式で出力
"C:\Program Files\Google\Chrome\Application\chrome.exe" --headless=old --disable-gpu --window-size=1920,1080 --hide-scrollbars --lang=ja-JP --screenshot=C:\var\temp\hoge.png https://www.yahoo.co.jp/
# -> 426519 bytes written to file C:\var\temp\hoge.png
# PDF形式(A4縦)で出力
"C:\Program Files\Google\Chrome\Application\chrome.exe" --headless=old --disable-gpu --window-size=1920,1080 --hide-scrollbars --lang=ja-JP --no-pdf-header-footer --print-to-pdf=C:\var\temp\hoge.pdf https://www.yahoo.co.jp/
# -> 1342161 bytes written to file C:\var\temp\hoge.pdf
Chrome112以降の推奨されたやり方
Puppeteer(パペッティア)でchrome-headless-shellのバイナリを取得して実行.
- 前提:node.js[npm]がインストール済みであること。
npx --yes @puppeteer/browsers install chrome-headless-shell@stable
# Need to install the following packages:
# @puppeteer/browsers@2.4.1
# Downloading chrome-headless-shell 130.0.6723.116 - 105.6 MB [====================] 100% 0.0s
# chrome-headless-shell@130.0.6723.116 C:\var\temp\chrome-headless-shell\win64-130.0.6723.116\chrome-headless-shell-win64\chrome-headless-shell.exe
cd C:\var\temp\chrome-headless-shell\win64-130.0.6723.116\chrome-headless-shell-win64\
# PNG形式で出力
chrome-headless-shell.exe --disable-gpu --window-size=1920,1080 --hide-scrollbars --lang=ja-JP --screenshot=C:\var\temp\hoge.png https://www.yahoo.co.jp/
# -> 442004 bytes written to file C:\var\temp\hoge.png
# PDF形式(A4縦)で出力
chrome-headless-shell.exe --disable-gpu --window-size=1920,1080 --hide-scrollbars --lang=ja-JP --no-pdf-header-footer --print-to-pdf=C:\var\temp\hoge.pdf https://www.yahoo.co.jp/
# -> 1230406 bytes written to file C:\var\temp\hoge.pdf
RHEL系Linuxでも確認.
$ cat /etc/redhat-release
AlmaLinux release 9.4 (Seafoam Ocelot)
$ dnf install -y https://dl.google.com/linux/direct/google-chrome-stable_current_x86_64.rpm
$ google-chrome --version
Google Chrome 130.0.6723.116
$ which google-chrome
/usr/bin/google-chrome
# とりあえずNoto Sans Japaneseフォント
$ curl -O https://noto-website-2.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip && unzip NotoSansCJKJP-hinted.zip -d ~/.fonts/
# IPAフォントはお好みで
# curl -O https://moji.or.jp/wp-content/ipafont/IPAexfont/IPAexfont00401.zip && unzip IPAexfont00401.zip -d ~/.fonts/
# フォントキャッシュクリア
$ fc-cache -fv
$ google-chrome --headless=old --no-sandbox --disable-setuid-sandbox --window-size=1920,1080 --hide-scrollbars --lang=ja-JP --screenshot=/tmp/hoge.png https://www.yahoo.co.jp/
# -> 532293 bytes written to file /tmp/hoge.png
$ google-chrome --headless=old --no-sandbox --disable-setuid-sandbox --window-size=1920,1080 --hide-scrollbars --lang=ja-JP --no-pdf-header-footer --print-to-pdf=/tmp/hoge.pdf https://www.yahoo.co.jp/
# -> 1174386 bytes written to file /tmp/hoge.pdf
# Old Headless mode will be removed from the Chrome binary soon. Please use the new Headless mode (https://developer.chrome.com/docs/chromium/new-headless) or the chrome-headless-shell which is a standalone implementation of the old Headless mode (https://developer.chrome.com/blog/chrome-headless-shell).
# headless=oldオプションだからchrome-headless-shell使えぃ! と促される。
$ cd /usr/local/src
$ npx --yes @puppeteer/browsers install chrome-headless-shell@stable
Downloading chrome-headless-shell 130.0.6723.116 - 112.4 MB [====================] 100% 0.0s
chrome-headless-shell@130.0.6723.116 /usr/local/src/chrome-headless-shell/linux-130.0.6723.116/chrome-headless-shell-linux64/chrome-headless-shell
$ ln -s /usr/local/src/chrome-headless-shell/linux-130.0.6723.116/chrome-headless-shell-linux64/chrome-headless-shell /usr/local/bin/chrome-headless-shell
$ ls -l /usr/local/bin/ | grep "chrome"
lrwxrwxrwx 1 root root 109 Nov 7 11:47 chrome-headless-shell -> /usr/local/src/chrome-headless-shell/linux-130.0.6723.116/chrome-headless-shell-linux64/chrome-headless-shell
# warningが出るけど気にしない。
$ chrome-headless-shell --no-sandbox --disable-setuid-sandbox --window-size=1920,1080 --hide-scrollbars --lang=ja-JP --screenshot=/tmp/hoge.png https://www.yahoo.co.jp/
# -> 531620 bytes written to file /tmp/hoge.png
$ chrome-headless-shell --no-sandbox --disable-setuid-sandbox --window-size=1920,1080 --hide-scrollbars --lang=ja-JP --no-pdf-header-footer --print-to-pdf=/tmp/hoge.pdf https://www.yahoo.co.jp/
# -> 1127228 bytes written to file /tmp/hoge.pdf
ls -l /tmp | grep "hoge"
-rw-r--r-- 1 root root 1127228 Nov 7 11:51 hoge.pdf
-rw-r--r-- 1 root root 531620 Nov 7 11:51 hoge.png
macOS Zshで確認。
- Google Chromeでは動く。chrome-headless-shellバイナリは動かない?
# 標準パスのGoogle Chromeバイナリを実行。
% "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" --headless=old --no-sandbox --disable-setuid-sandbox --window-size=1920,1080 --hide-scrollbars --lang=ja-JP --no-pdf-header-footer --print-to-pdf=/tmp/hoge.pdf https://www.yahoo.co.jp/
% ls -la | grep hoge
-rw-r--r--@ 1 nqj26641 wheel 1877191 11 7 20:48 hoge.pdf
% sudo npx --yes @puppeteer/browsers install chrome-headless-shell@stable
% sudo ln -s /usr/local/src/chrome-headless-shell/mac_arm-130.0.6723.116/chrome-headless-shell-mac-arm64/chrome-headless-shell /usr/local/bin/chrome-headless-shell
% which chrome-headless-shell
/usr/local/bin/chrome-headless-shell
# icudtl.dat not found in bundle ... NG
Puppeteerで動かす場合.
「A4横」用紙設定で、PDF帳票をChrome Headlessにてブラウザレンダリング出力したい場合。
⇒Google Chrome本体のHeadlessモードに引数を当てるだけではムリ。
Chrome DevTools Protocolを利用した、Node.js「Puppeteer」やPython「Selenium」+WebDriverなどでChrome相当でオプション制御可能なのテストツールで出力が可能となる。
開発者ツール上で可能なフルページスクリーンショットなどにも対応しているので、こちらの方が利活用しやすいと思われる。
npm --version
10.9.0
# Chromium欲しいのでpuppeteer-coreではなくpuppeteer全体.
npm i --save puppeteer puppeteer-extra puppeteer-extra-plugin-stealth
puppeteer --version
23.7.0
では、以下ファイルを作成して実行.
例:node prtscr.js https://qiita.com/ qiitaScreenShot
のように実行する.
prtscr.js
/**
* Puppeteerでスクリーンショット(PNG/PDF)取得.
* node prtscr.js 【URL】 【ファイル名(拡張子なし)】
*/
if (process.argv.length > 4) {
console.log('arguments error.');
return;
}
// 第3引数=URLを取得.
const TARGET_URL = process.argv[2] ? process.argv[2] : 'https://yahoo.co.jp/';
const FILE_NAME = process.argv[3] ? process.argv[3] : 'tmpPrtScr';
const puppeteer = require('puppeteer-extra');
const StealthPlugin = require('puppeteer-extra-plugin-stealth');
puppeteer.use(StealthPlugin());
(exports.handler = async(event, context) => {
const viewportWidth = 1920;
const viewportHeight = 1080;
const browser = await puppeteer.launch({
headless: 'new',
args: [
'--no-sandbox',
'--disable-setuid-sandbox'
],
defaultViewport: {
width: viewportWidth,
height: viewportHeight
},
});
const page = await browser.newPage();
page.setViewport({width: viewportWidth, height: viewportHeight})
await page.setExtraHTTPHeaders({
'Accept-Language': 'ja'
});
const response = await page.goto(TARGET_URL, { waitUntil: 'networkidle2' });
// await page.waitForNavigation({waitUntil: 'networkidle2', timeout: (1000 * 5)});
if (response.status() == 200) {
// PNGスクショの場合.
await page.screenshot({
path: FILE_NAME + '.png',
fullPage: true,
});
// PDFの場合. A4横用紙.
await page.pdf({
path: FILE_NAME + '.pdf',
displayHeaderFooter: false,
format: 'a4', // 小文字
landscape: true,
// グレースケール/白黒帳票にはできない。
});
const pageTitle = await page.title();
console.log(TARGET_URL + ' -> ' + pageTitle);
await page.close();
}
await browser.close();
})();
- 何かあればコメント等ヨロシクオネガイシマス。