ことの起こり
妻(プログラミングに興味はあるけど、特別ITに詳しいわけではない普通の主婦。どちらかというとむしろ理数系は苦手)がどこかで、スクレイピングなる単語を聞いてきたらしく、「puppeteerというソフトを使えば、Webサイトを自動的に定期取得したりということができるらしい」「面白そうだからやってみたい」と言われたことが始めたきっかけ。
それからどした
とりあえず、私がpuppeteerなるものを知らなかったので調べてみました。
- node.js のモジュールで、chromeをプログラム的に操作するものらしい。
- 使いこなせたらテストとか楽そう。
- 自分も興味が出たから、まぁ、暇なときにやってみるか。
という流れで、ひとまず環境を作ってあげることに。
本格的な開発で使うわけではないので、古くてもいい代わりに、プライバシーをとかく気にしがちな妻が自由にできる環境が良いだろうということで、自宅で眠っていた13年前のLet's noteを引っ張り出してみました。
元々、すでに数年前にXubuntuに入れ替えて眠らせていた端末だったのでアップデートかけるくらいで使えたらめっけ物だなぁ〜と思って動かしてみたら、意外と動く。でも、リポジトリが古すぎてインストールできたnodeのバージョンが古く、肝心のpuppeteerが動かない。
ということで、まぁ、折角の機会なのでXubuntuのLTSでもある18.04.2をクリーンインストール。
まっさらな環境を立ち上げました。
詰まったこと
あとはドキュメントなり関連情報調べながら適当に入れていけばいいだろう〜と思って、qiitaなりを参考に、
npm i puppeteer
と実行してから、サンプルをカキカキ。
node example.js
と実行してみたら、もろにエラー。あれ?
しかもエラーメッセージが
node example.js
(node:10017) UnhandledPromiseRejectionWarning: Error: Failed to launch chrome!
/home/tezuka/node/node_modules/puppeteer/.local-chromium/linux-624492/chrome-linux/chrome: 1: /home/tezuka/node/node_modules/puppeteer/.local-chromium/linux-624492/chrome-linux/chrome: Syntax error: "(" unexpected
TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md
at onClose (/home/tezuka/node/node_modules/puppeteer/lib/Launcher.js:360:14)
at Interface.helper.addEventListener (/home/tezuka/node/node_modules/puppeteer/lib/Launcher.js:349:50)
at emitNone (events.js:111:20)
at Interface.emit (events.js:208:7)
at Interface.close (readline.js:370:8)
at Socket.onend (readline.js:149:10)
at emitNone (events.js:111:20)
at Socket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
(node:10017) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:10017) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
なんて感じでリンクされてるトラブルシューティングのドキュメント読んでも今ひとつわからない。
というより何より、一番最初のエラーメッセージ、明らかにlaunch関数で詰まっているし、エラーメッセージが出るにしてもこれ、構文エラーって明らかにおかしいよね?
当初npmの環境作った場所が日本語パスの下にあったので、そのへんが問題かと思って別のパスはいかに環境作り直してみたりもしたが状況は変わらず。
どうもpuppeteer配下に一緒にセットアップされているchromeが壊れてるんじゃないかなぁ〜ということで、なんとかこの下のchromeを使わずに動かす方法がないか調査。
で、どうした。
公式文書を見ると、どうもpuppeteerの他に、ブラウザをバンドルしないpuppeteer-coreというバージョンが提供されている様子。
これを使えばいけそうだが、connectしたりなんだかんだと、ちょっと使い方が複雑になりそう。
私はともかく、本を頼りになんとかしようとしている妻はきっと挫折するだろう。どうにかならないかと思ってもう公式ドキュメントをプラプラ見ていたらこんな一文を見つけた。
const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'});
お?これってもしかして任意の場所のChrome立ち上げられるんじゃ?
ということで、Xubuntuのaptでインストールできた、chromiume-browserを指定する以下の形のexample.jsを作成。
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({executablePath: '/usr/bin/chromium-browser'});
const page = await browser.newPage();
await page.goto('https://www.yahoo.co.jp');
await page.screenshot({path: 'yahoo.png'});
await browser.close();
})();
node example.js
を実行したところ、無事、yahoo.pngの画像が作成されました。
ひとまずこれで動くようになりましたので、もし同じようなことでお困りの方がいましたら参考にどうぞ。
結局、なんでバンドルされていたブラウザがエラーになったのかは不明なんですが、どなたかご存じの方がいましたら教えていただけますと幸いです。