Node, Puppeteer, Dockerでスクレイピングしてみる
こんにちは。asatoです。
スクレイピングというテクニックがあります。
Webサイトなどを解析してほしい情報を自動的に入手したりできるやつです。勉強がてらやってみたのでまとめです。
※ スクレイピングを悪用してはいけないです。サイトには負荷がかかります。利用規約で禁止しているサービスもあります。ご利用は計画的に。
なにする?
今回は自作プロダクト「spaces.bz」を題材に、Google検索で「spaces.bz」を検索してトップに表示されているかどうかをチェックするプログラムを組んでみようと思います。
トップに出てきたら嬉しいですが、毎日手でやるのは面倒ですよね♪
アーキテクチャ
今回はNodeを使います。理由は僕が使い慣れているからです。
あと、Dockerも使います。理由は僕がローカルに色々入れたくないからです。
あと、画面操作やデータの取得はpuppeteerを使います。理由は前使ったことがあるからです。
あんまり理由がいい加減でごめんなさい。そんなに特殊な選択はしてないのでね。
一応バージョン情報。
- docker: 20.10.8
- node: 17.4.0
- puppeteer: 13.3.0
ローカルに入っているのはdockerだけです。あとはこれから入れてきますよー。
おおまかな手順
- puppeteerを動かすnodeコンテナをつくる
- スクレイピングのコードを書く
puppeteerを動かすnodeコンテナをつくる
Dockerfile
とdocker-compose.yml
を作成します。
# Dockerfile FROM node WORKDIR /app VOLUME /app/node_modules RUN apt-get update \ && apt-get install -y wget gnupg \ && wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \ && sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list' \ && apt-get update \ && apt-get install -y google-chrome-stable fonts-ipafont-gothic fonts-wqy-zenhei fonts-thai-tlwg fonts-kacst fonts-freefont-ttf libxss1 \ --no-install-recommends \ && rm -rf /var/lib/apt/lists/* RUN yarn add puppeteer CMD ["node", "index.js"]
# docker-compose.yml version: "3" services: app: build: . volumes: - .:/app
Dockerfile
の中でpuppeteerいれちゃいます。
Dockerfile
でRUN apt-get ~
のところでchromeをインストールしてますね。
puppeteerのトラブルシューティングにかかれていますが、これをしないとpuppeteerがdockerコンテナの中でうまく動けません。
これでビルドしておけば、とりあえず環境の準備は完成です(≧∇≦)b
$ docker compose build
スクレイピングのコードを書く
環境が整ったのでスクレイピングのコードを書いてみます。
Dockerfile
で起動時にnode index.js
のコマンドを実行するようにしているので、index.js
にコードを書いていきます。
# index.js const puppeteer = require('puppeteer') !(async() => { const browser = await puppeteer.launch({ args: [ '--no-sandbox', '--disable-dev-shm-usage' ] }) const page = await browser.newPage() // googleのトップページにアクセス await page.goto('https://google.com/') // 検索フォームに'spaces.bz'と入力 await page.type('input.gLFyf.gsfi', 'twitter spaces') // Enterキーを押下 await page.keyboard.press('Enter') // 検索結果が表示されるまで待つ await page.waitForSelector('cite.iUh30.tjvcx') // 検索結果トップのURLを取得 const topUrl = await page.$eval('cite.iUh30.tjvcx', el => el.innerText) // 検索結果トップが自分のサイトならOKメッセージ、違えばそのサイトのURLをコンソールに出力 if (topUrl === 'https://spaces.bz') { console.log('spaces.bzは検索トップに表示されています🎉') } else { console.log(`検索トップは「${topUrl}」です...`) } browser.close() })()
シンプルですね!コメントアウトも入れたので、それぞれの処理のイメージを掴んでもらえると嬉しいです。
具体的なpuppeteerの使い方は公式を御覧ください!色々できます。
さて、これを実行してみると...
$ docker compose up spaces.bzは検索トップに表示されています🎉
いえーい(≧∇≦)/
試しに検索キーワードを「twitter spaces」にしてみると...
$ docker compose up 検索トップは「https://help.twitter.com › ヘルプセンター › ツイート」です...
ぬーん(´・ω・`)
おわり
はい!Nodeでスクレイピングできました!
puppeteerも入っているのでUI操作も可ですね。
優しいスクレイピングライフを!