Nuxt on Dockerでpuppeteer使ってスクレイピングする。
はじめに
あーあ、スクレイピングしたいな。
ということで Nuxt on Docker でスクレイピングします。
node系だとpuppeteerというライブラリがスクレイピングするのにおすすめっぽかったので、NuxtのserverMiddlewareからサクッとスクレイピングします。
あまり人に迷惑をかけてはいけないと言われて育ったので、スクレイピングは自分のサイトにします。(ログイン不要だよ。ぜひ使ってみてね♪)
toribure | ひとりでもチームでも使えるシンプルイズベストなブレストツール
やや宣伝ですね。トップページにかわいい鳥(いらすとや)の画像があります。今回はこれをスクレイピングで取ってきて表示させようと思います。
Nuxt on Dockerの準備
このあたりは他にも記事がいっぱいあると思うのでさらーっと。
ちなみに環境は
$ docker -v
Docker version 19.03.13-beta2, build ff3fbc9d55
$ docker-compose -v
docker-compose version 1.26.2, build eefe0d31
でした。
Nuxtアプリを作る
$ docker run --rm -it -w /app -v `pwd`:/app node yarn create nuxt-app scraping
? Project name: scraping
? Programming language: JavaScript
? Package manager: Yarn
? UI framework: None
? Nuxt.js modules: Axios
? Linting tools:
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools:
axios
だけ後で使うので意識的に入れておきます。
ちなみに記事作成時点でnode:latest
イメージのバージョンは14.9.0、create-nuxt-app
のバージョンはv3.2.0で、nuxt
は2.14.0が入りました。
Dockerfile, docker-compose.ymlを準備する
ここからは今できたばかりのscraping/
ディレクトリが作業ディレクトリです。
$ cd scraping
FROM node
ENV HOME=/app \
LANG=C.UTF-8 \
TZ=Asia/Tokyo \
HOST=0.0.0.0
WORKDIR ${HOME}
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/*
COPY package.json ${HOME}
COPY yarn.lock ${HOME}
RUN yarn install
COPY . ${HOME}
EXPOSE 3000
CMD ["yarn", "run", "dev"]
RUN apt-get ...
あたりはpuppeteerのトラブルシューティングに詳細があります。ブラウザやフォントがコンテナ内に用意されていないとエラーになるってことです。
version: "3"
services:
nuxt:
build: .
volumes:
- .:/app
ports:
- 3000:3000
ここまで終わったら一度コンテナをビルドしておきます。
$ docker-compose build
スクレイピングアプリを作るぞ
puppeteer導入
yarnでいれちゃいます。
$ docker-compose run --rm nuxt yarn add puppeteer
APIを作る
serverMiddlewareを使っていきます。公式でも紹介されているexpress-templateを参考にserverMiddlewareをAPIとして通してスクレイピングしていきます。
export default {
...
,
serverMiddleware: {
'/api': '~/api'
}
}
これで/api
のアクセスを~/api/index.js
に流します。のでファイル作ります。
$ mkdir api
$ touch api/index.js api/scraping.js
ファイルを2つ作りましたがindex.js
が受け口になっていて実処理はscraping.js
にやらせようと思います。
const app = require('express')()
const scraping = require('./scraping')
app.get('/get_image', async(req, res) => {
const image = await scraping.getImage()
res.send(image)
})
module.exports = {
path: '/api',
handler: app
}
こちらは/api/get_image
にアクセスがあったらscraping.js
のget_image()
メソッドを呼び出すようにしてます。
const puppeteer = require('puppeteer')
async function getImage() {
const browser = await puppeteer.launch({
args: [
'--no-sandbox',
'--disable-dev-shm-usage'
]
})
const page = await browser.newPage()
await page.goto("https://toribure.herokuapp.com/")
const image = await page.evaluate(() => {
return document.getElementsByTagName("main")[0].getElementsByTagName("img")[0].src
})
return image
}
module.exports = {
getImage
}
ほぼpuppeteer公式のREADMEに則ってます。
page.evaluate
を使うことで要素を取得したり操作したりできるんですね。
今回のスクレイピング先(https://toribure.herokuapp.com/)のHTML構造をDeveloper toolなどで見ると分かる通り、全体で1つしかないmain
要素配下に1つしかないimg
要素がターゲットとしてる鳥さんの画像です。(汚い構造してますがご愛嬌です)
そこまでわかれば通常のjsと同じように要素を取得するだけです。
ここまででAPIサイドはコーディング終了です。
フロントはさっくりと
もう疲れてきたのでフロントはボタン押したら画像表示されるくらいで。
<template>
<div>
<button @click="showBird">Scraping!!</button>
<br>
<img v-if="src" :src="src">
</div>
</template>
<script>
export default {
data() {
return {
src: ""
}
},
methods: {
async showBird() {
this.src = await this.$axios.$get("/api/get_image")
}
}
}
</script>
完成!!
動作確認
かわいい鳥が出てきました♪
さいごに
ここまでできれば、あとはDOM操作の世界なので、対象のページの構造を理解してjsを書けば何でもスクレイピングできますね。
スクレイピングは禁止しているサイトもあるのでその点は注意しながらいろんなアイデアを実現できればいいですね!
参考
Author And Source
この問題について(Nuxt on Dockerでpuppeteer使ってスクレイピングする。), 我々は、より多くの情報をここで見つけました https://qiita.com/at-946/items/5a04baafcbfe13db6ea7著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .