CentOS7でPuppeteerを使う

JavaScriptでDOM操作をして要素を出力しているページに対してスクレイピングを行うためにPuppeteerが必要になりそうでしたのでさわりだけ試しました。


とりあえず動かしてみたい

とりあえずREADME.mdの最初のスクリーンショットをとるサンプルhttps://qiita.com/のページ全体を対象として動作させてみることにしました。


example.js

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を実行

とりあえず無事に以下のスクリーンショットが取れました。

example1.png


念のため読み込みが無くなってからスクリーンショットしたい

- 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を実行

example2.png


英語になっているので言語設定やユーザーエージェントを設定したい


言語設定

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を実行


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);
});


example3.png