JavaScriptでDOM操作をして要素を出力しているページに対してスクレイピングを行うためにPuppeteerが必要になりそうでしたのでさわりだけ試しました。
とりあえず動かしてみたい
とりあえずREADME.mdの最初のスクリーンショットをとるサンプルをhttps://qiita.com/
のページ全体を対象として動作させてみることにしました。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://qiita.com/');
await page.screenshot({path: 'example.png'});
await browser.close();
})();
node example.js
を実行してみる
node_modules/puppeteer/.local-chromium/linux-588429/chrome-linux/chrome: error while loading shared libraries: libXcomposite.so.1: cannot open shared object file: No such file or directory
TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
Troubleshootingを確認してみると
CentOS Dependenciesという項目があったのでCheck out discussionsを確認してみたところ
From a minimal CentOS 7 setupとあったので以下を実行
yum -y install libX11 libXcomposite libXcursor libXdamage libXext libXi libXtst cups-libs libXScrnSaver libXrandr alsa-lib pango atk at-spi2-atk gtk3
再度node example.js
を実行してみる
ERROR:zygote_host_impl_linux.cc(89)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.
TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
Troubleshootingを確認してみると
Chrome Headless fails due to sandbox issuesという項目があったので
- const browser = await puppeteer.launch();
+ const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox']});
に修正して再度node example.js
を実行
とりあえず無事に以下のスクリーンショットが取れました。
念のため読み込みが無くなってからスクリーンショットしたい
- await page.goto('https://qiita.com/');
+ await page.goto('https://qiita.com/', {waitUntil : 'networkidle0'});
waitUntil : 'networkidle0'
だと戻ってこないページがあったので
waitUntil: 'domcontentloaded'
の後に
page.waitFor(milliseconds)
で待機する方法が無難そうです。
それでも返ってこない場合は順番に試してく方法がよさそうです。
こちらで使用しているように以下の様なオプションリストを作ったりして。
optionList = [
{waitUntil: 'load'},
{waitUntil: 'domcontentloaded'},
{waitUntil: 'networkidle0'},
{waitUntil: 'networkidle2'}
];
文字化けを直したい
yum -y install ipa-gothic-fonts xorg-x11-fonts-100dpi xorg-x11-fonts-75dpi xorg-x11-utils xorg-x11-fonts-cyrillic xorg-x11-fonts-Type1 xorg-x11-fonts-misc
スクリーンショットの幅を広げたい
+ await page.setViewport({width: 1280, height: 720});
(widthのみの指定ではエラーになりました。)
全ページにしたい
- await page.screenshot({path: 'example.png'});
+ await page.screenshot({path: 'example.png', fullPage: true});
修正して再度node example.js
を実行
英語になっているので言語設定やユーザーエージェントを設定したい
言語設定
How to specify browser language in Puppeteer
これによると
browserのオプションで設定する方法
pageのメソッドで設定する方法
がある様子。
今回はbrowserのオプションで設定してみます。
+ '--lang=ja,en-US;q=0.9,en;q=0.8',
ユーザーエージェント設定
browserのオプションで設定する方法
browserのメソッドで設定する方法
pageのメソッドで設定する方法
pageのemulateのオプションで設定する方法
がある様子。
今回はbrowserのオプションで設定してみます。
+ '--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
修正して再度node example.js
を実行
const puppeteer = require('puppeteer');
(async () => {
try {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-setuid-sandbox',
'--lang=ja,en-US;q=0.9,en;q=0.8',
'--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
]
});
const page = await browser.newPage();
await page.goto('https://qiita.com/', {waitUntil : 'domcontentloaded'});
await page.waitFor(2000);
await page.setViewport({width: 1280, height: 720});
await page.screenshot({path: 'example.png', fullPage: true});
await page.close();
await browser.close();
} catch (error) {
throw error;
}
})().catch((error) => {
console.log(error);
process.exit(1);
});