DockerでHeadless Chrome(puppeteer)を使う
DockerでHeadless Chrome(puppeteer)を使う
About
ブラウザ操作にはjsのライブラリpuppeteer
を使う
GitHub: https://github.com/puppeteer/puppeteer
Docker Image
日本語フォントに対応したHeadless Chrome Dockerコンテナ
FROM mhart/alpine-node:12 ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true RUN apk update && apk add --no-cache nmap && \\ echo @edge http://nl.alpinelinux.org/alpine/edge/community >> /etc/apk/repositories && \\ echo @edge http://nl.alpinelinux.org/alpine/edge/main >> /etc/apk/repositories && \\ apk update && \\ apk add --no-cache \\ chromium \\ harfbuzz \\ ttf-freefont \\ nss # 日本語フォントをインストールする RUN mkdir /noto ADD https://noto-website.storage.googleapis.com/pkgs/NotoSansCJKjp-hinted.zip /noto WORKDIR /noto RUN unzip NotoSansCJKjp-hinted.zip && \\ mkdir -p /usr/share/fonts/noto && \\ cp *.otf /usr/share/fonts/noto && \\ chmod 644 -R /usr/share/fonts/noto/ && \\ fc-cache -fv WORKDIR / RUN rm -rf /noto
Chromeのバージョンが違うと動かないことがある
上記のDockerfileだと72が入るのでpuppeteer
のバージョンを合わせてインストールする。
npm install puppeteer-core@chrome-72
TypeScriptで使うなら
npm install -D @types/pupeteer
executablePath
を指定してあげる。Macとかのホストマシンで動かす場合はなくても大丈夫。
--no-sandbox
を指定しないとルート権限で動かせない。
const browser = await puppeteer.launch({ executablePath: \"/usr/bin/chromium-browser\", args: ['--no-sandbox'], defaultViewport: { width: 1920, height: 1090 }, });
APIはここ https://github.com/puppeteer/puppeteer/blob/master/docs/api.md
スクリーンショットを取る
await page = browser.newPage(); page.goto(\"https://example.com\"); await page.screenshot({ path: \"example.png\" });
ボタンを押して遷移を待つ
await Promise.all([ page.tap(\"button\"), page.waitForNavigation({ waitUntil: \"networkidle2\" }) ]);
ファイルをアップロードして待つ
const fileInputHandle= await page.$(\"input\"); await fileInputHandle.uploadFile(\"example.png\"); // アップロード後に変化するDOMを指定するとアップロード完了を待てる await page.waitForSelector(\"#uploaded\");
複数のDOMに対して処理を行う
var texts: Array<string> = await page.$$eval(\"li\", (elements) => elements.map(el => el.innerHTML));
Cookieを再利用する
保存
var cookies = await page.cookies(); writeFileSync(\"cookies.json\", JSON.stringify(cookies));
セット
var cookies: Cookie[] = JSON.parse(readFileSync(\"cookies.json\").toString()); await page.setCookie(...cookies);
参考
https://github.com/mhart/alpine-node https://help.apify.com/en/articles/1640711-how-to-log-in-to-a-website-using-puppeteer https://stackoverflow.com/questions/46948489/puppeteer-wait-page-load-after-form-submit https://qiita.com/go_sagawa/items/85f97deab7ccfdce53ea https://qiita.com/dd511805/items/dfe03c5486bf1421875a https://blog.logrocket.com/how-to-set-up-a-headless-chrome-node-js-server-in-docker/ https://hub.docker.com/r/justinribeiro/chrome-headless/ https://developers.google.com/web/updates/2017/04/headless-chrome