Puppeteerでテキストデータを取得する(スクレイピング)

この記事ではNode.jsのライブラリPuppeteerを使ってWebページに記載されている情報(テキストデータ)を取得する方法を紹介します。

取得したテキストデータをテキストファイルに書き込むところまでを実践します。

  • 毎日データを取ってくる作業を自動化したい人
  • 毎日データを取ってきてアイディアを実現させたい人

上記の方を対象とした記事となります。

スポンサーリンク

Webページからタグ単位でテキストデータを探す

Webページからテキストデータを取得する場合はHTMLタグ単位でデータを指定します。

  1. タグを使って指定できる場合は、タグで指定してデータを取得することができます。
  2. タグで識別できない場合は、タグで複数のデータを絞ってから目的のデータを検出します。

それぞれのパターンについて見ていきます。

※サンプルコードはYahoo天気からデータを取得するコードです。

タグで一つに絞れるケース

タグやclass属性で一つに絞れる場合はタグやclass属性でデータを取得します。

以下は「<span class=”time”>2019/8/1</span>」というタグで設定されている今日の日時を取得するサンプルコードです。

let resultSelector = await page.$('span.time');
let value = await (await resultSelector.getProperty('textContent')).jsonValue()
console.log(value)

page.$$()でselector(タグ、class属性等)を設定するとreturnで<Promise<?ElementHandle>>を返します。(Puppeteer API参照)

return値の結果は「.getProperty(‘textContent’)」、「.jsonValue()」でテキストデータを取り出すことができます。(どちらもawaitが必要です)

難しいことを言っていますが、上記のサンプルをコピペしてほしいデータを取れればOKです。

タグで一つに絞れないケースは配列で処理(目印をつけて探す)

タグやclass属性で一つに絞れない場合は一手間必要です。

例えばYahoo天気で東京の気温を取得したい場合に、<p class=”temp”>35/27</p>となっているとします。

この場合、東京以外の仙台や名古屋の気温も<p class=”temp”>のタグ構成となっているため<p class=”temp”>は使えません。

そのため、階層を少しずつ上がっていき、必要な気温と特定できる階層(タグ)を指定します。

タグ構成の例

この場合は「東京」および、「35/27」が含まれている階層が条件になります。

<li class=”point pt4410″>で特定できそうですが、ここではあえて<dl>で指定してみます。(その方が使えるシーンが増えると思うので)

let resultSelectors = await page.$('dl');
let resultsArray = [];
let tokyoFlag = "";
for (let i = 0; i < resultSelectors.length; i++) {
    resultsArray.push(await (await resultSelectors[i].getProperty('textContent')).jsonValue())
    if(resultSelectors[i].match(/東京/)){
        tokyoFlag = i;
        break;
    }
}
console.log(resultsArray[tokyoFlag])

先ほどの一つでタグを絞れるケースとの違いはpage.$$()を使っていることです。

Puppeteer APIに記載の通り、全セレクタの結果を取得してくるので配列処理する必要があります。

結果の配列(resultsArray)にはWebページのdlタグの全データが含まれます。(東京のデータ以外の仙台や名古屋の気温も)

そのため「.match(/東京/)」を指定して「東京」が含まれる配列の添字(i)をtokyoFlagに入れています。

最初の例で違うデータが取れちゃったって人は、こっちのサンプルで取得すればOKです。

テキストを加工するサンプル(substringやlastIndexOf)

一つ前で取得したデータでは気温(35/27)が必要ですが、東京や湿度や不要なスペースが含まれています。

substringやlastIndexOf等の文字列を加工する関数を使って取り除いていきます。

文字列の関数の詳細は割愛します。

ここでは「/」の前2桁から後2桁を取得するサンプルを載せておきます。

let result = tagText2[indicator2]
let mark = result.lastIndexOf("/")
let temperature = result.substring(mark-2,mark+3)

取得したデータをテキストファイルに書き込む

最後に取得したデータをテキストファイルに書き込む箇所となります。

fsというライブラリを使うのでfsをインストールしておきます。

npm install fs

コード上はfsのimportをコードの先頭部分で記載しておきます。
fs.appendFileは追記型で実行するたびにデータが追記されていきます。

temperature_tokyo.txtはファイル名、temperatureは変数や配列を指定してください。

temparatureに日付や改行(+”\n”)を入れておくと綺麗に処理することができます。

const fs = require('fs');
(中略)
fs.appendFile("./temperature_tokyo.txt", temperature, (err) => {
    if (err) throw err;
});

まとめ

この記事ではWebページのテキストデータを取得する方法を解説しました。

外部サーバに配置することで毎日データを取得できるようになりますので、ぜひチャレンジしてみてください。

おすすめ参考記事

Puppeteerで作ったプログラムを自動実行させるライブラリの紹介です

Puppeteerを学習できる数少ない書籍です。

外部サーバで稼働させるにはさくらVPSが手軽でおすすめです。

コメント

タイトルとURLをコピーしました