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で稼働させてみよう。

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

Node.jsのチュートリアルは動画学習が早く習得できます。私が利用しているのはUdemy です。
Node.jsの勉強法も参照ください。


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


ABOUT US

ケネ
はじめまして、ケネです。

Node.jsの技術情報を書いています。

一人でも多くの方と「自分でもできた」感覚を共有したいので、なるべくわかりやすく、実体験ベースでのブログを心がけています。
技術で自分の世界を広げましょう。

不明点や質問があればお気軽にコメントください。