パン工房

IT/F1/セカオワ/キングダムハーツ/鉄道

【Parser】GASでHTML解析する方法

こんにちは。

今日はGASでParserというライブラリを使ってHTMLを解析する方法を紹介します。簡単な情報収集をスクリプトを使って行うときに便利です。

HTMLの解析って難しい

WebサイトのHTMLをダウンロードして、そこから欲しい情報だけを抜き出すという情報収集は、プログラマーならよくやろうとすることなんじゃないかと勝手に思っていますが、HTMLのパースって結構難しいです。要素がかなり多かったり、文法ミスがあったり、そもそもHTMLがXMLほど文法が厳格ではないので文書構造を正しく理解することが難しいです。

HTMLの解釈には

  • 正規表現で頑張る
  • 高度なパーサーライブラリを使う
  • 諦める

といった選択肢があると思いますが、今回はもっと単純にHTMLの解析ができるGAS(Google Apps Script)のライブラリを紹介します。

Parser

それがParserというそのままの名前のライブラリです。このライブラリの仕様が面白く、抜き出したい要素の開始文字列、終了文字列、1個なのか複数なのかをメソッドチェーンで繋げていくと、その部分を文字列や配列で返してくれる、というものです。文章で書いても伝わらないのでコードにします。

const html = `
<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
  </head>
  <body>
    <h1>自己紹介</h1>
    <h2>名前</h2>
    <div class="name">パン</div>
    <h2>好きな果物</h2>
    <ul class="fruits">
      <li>バナナ</li>
      <li>りんご</li>
      <li>ぶどう</li>
      <li>スイカ</li>
    </ul>
  </body>
</html>
`

サンプルのHTMLを用意しました。GASでHTMLを取得するにはUrlFetchAppを使うと思いますが、今回は割愛します。

例えばこのHTMLから名前の「パン」を取得したいときは、

const name = Parser.data(html).from('<div class="name">').to('</div>').build()
console.log(name)
// パン

このように記述します。 Parser.data() にHTML文字列を入れ、 from() で開始文字列を、 to() で終了文字列を指定します。最後に build() を呼び出せば指定した箇所の文字列を取得できます。

好きな果物のように複数あるものを取得したいときは、

const fruitsContainer = Parser.data(html).from('<ul class="fruits">').to('</ul>').build()
const fruits = Parser.data(fruitsContainer).from('<li>').to('</li>').iterate()
console.log(fruits)
// [ 'バナナ', 'りんご', 'ぶどう', 'スイカ' ]

まず複数あるものの親要素をbuildで拾います。ここではfruitsContainerという変数に入れました。この時点で文字列になっているので、また別のParserに入れることができます。あとは複数あるものの共通部分を開始、終了に指定して、最後に iterate() を呼び出すと、配列の形で返却されます。

Parserをライブラリに追加する

ParserをGASで利用するには、ライブラリとして公開されているものを自分のスクリプトに追加する必要があります。

左のサイドバーから「エディタ」を選び、「ライブラリ」の横の「+」を押します。するとスクリプトIDの入力を要求されるので、

1Mc8BthYthXx6CoIz90-JiSzSafVnT6U3t0z_W3hLTAX5ek4w0G_EIrNw

を入力して「検索」を押します。Parserが見つかったらバージョン8(執筆時点での最新)を選択して追加します。


今回はGASで簡単にHTML解析ができるライブラリParserを紹介しました。

それではまた。