みなさん、こんにちは!うえはら(@tifoso_str)です。
Google Apps ScriptでWebスクレイピングしていて、値が取得できないということはありませんか?
別のWebサイトではちゃんと動いているのに、特定のサイトではWebスクレイピングできていない。
原因はWebサイトの表示にJavaScriptを利用しているからなのですが、これだけではよくわからないですよね。
そこで【JavaScriptで動作するWebページを色々な言語でスクレイピング】してその原因と解決法をお伝えしていきます。
Google Apps Scriptでは説明が難しいので、まずはVBAで解説していきます。
今回は「VBAでスクレイピングができない理由として考えるべきJavaScriptのこと」をお伝えします。
Google Apps Scriptでも解決法をお伝えしますので、何回かVBAにお付き合い下さい。
スクレイピングするページをChromeで検証する
まずは、今回スクレイピングするJavaScriptを使用しているWebページと、スクレイピングするのに必要になるタグの探し方を説明します。
Webスクレイピングするホームページ
今回は、沖縄県企業局のページで、ダムの貯水率を確認します。
今回スクレイピングする値は、日付と全11ダム合計の貯水率です。
Chromeの検証機能
WebページはHTMLという言語で記述されていて、「ページのソース」等と呼ばれています。
Chromeでは右クリックのメニューで「ページのソースを表示」で見ることができます。
Internet Explorerでは「ソースの表示」です。
Webスクレイピングではこの「ページのソース」を全て取得して、必要部分を抜出しています。
一度、ページのソースを表示してもらえるとわかるとおもいますが、この中から、目的の箇所を探すのは大変です。
こんなとき、威力を発揮するのが、Chromeの検証機能です。
右クリックで出てくるメニューの「検証」で、確認できます。
検証機能を利用すると、画面右側に色々と出てくると思います。
(場所はメニューで変更できるので、画面下だったり別ウィンドウだったりするかもしれません。)
Elementsに表示されるHTMLにカーソルを合わせるとWebページの該当部分が強調表示されます。
これで、該当箇所が簡単に見つけられますね!
HTML構文は入れ子構造になっていることが多いので、目的の箇所にたどり着くまでには「▼」を何回かクリックする必要があると思います。
今回でいえば、日付と貯水率はそれぞれ下記の部分です。
日付 <span id="chosui_hiduke">06月21日</span> 貯水率72.1
VBAのHTTP通信でWebスクレイピング
それでは、VBAのHTTP通信を利用してWebスクレイピングしてみます。
VBAでHTTP通信をするには「Microsoft XML, v6.0」ライブラリを利用します。
詳細については、こちらの記事をご覧下さい。
Webページからソースを読み込んで、日付と貯水率をイミディエイトウィンドウに表示させます。
Sub HTTP通信() Dim httpReq As XMLHTTP60 Set httpReq = New XMLHTTP60 httpReq.Open " GET", "https://www.eb.pref.okinawa.jp/kassui/" httpReq.send 'HTTPリクエスト送信 Do While httpReq.readyState < 4 '処理待ち DoEvents Loop Dim htmlDoc As Object Set htmlDoc = New HTMLDocument htmlDoc.write httpReq.responseText Dim hiduke As IHTMLElement Set hiduke = htmlDoc.getElementById("chosui_hiduke") Debug.Print "■日付は「" & hiduke.innerHTML & "」です。" Dim chosuiritsu As IHTMLElement Set chosuiritsu = htmlDoc.getElementById("ritsu_today4") Debug.Print "■本日の貯水率は「" & chosuiritsu.innerHTML & "」です。" Set httpReq = Nothing Set htmlDoc = Nothing End Sub
実行して、イミディエイトウィンドウを確認してみます。
?取得できてないですね?
原因は、このWebページがサーバーからソースを読み込んだ後に、ブラウザー(Chromeなど)でJavaScriptを実行して画面に表示しているからです。
下の図を例に、もう少し簡単に説明しますね。
Webページを見るときは、サーバーから情報をもらうために「HTTPリクエスト」を送ります。
それを受けて、サーバーは「HTTPレスポンス」でWebページの情報を返します。
このときにボックスには、日付は入っていません。
先程、Webスクレイピングしたときは、この情報を取得していいたので、日付がなかったんです。
それではいつ日付が入るかです。
サーバーから返ってきた情報には「下のBoxに今日の日付を表示して」というJavaScriptの命令が入っています。
この命令をブラウザーが実行して日付が表示されます。
Webページを表示するのに、裏ではいろいろやってるんですね。
さて、これを解決する為にどうすればいいかというと、一度、ブラウザーでこのWebページを処理させてあげればいいわけです。
その後に、必要な値を取得すればO.K.ですね。
まとめ
このまま、解決法も書いていきたいのですが、ちょっと長くなったので、今回はここまでとします。
今回は「VBAでスクレイピングができない理由として考えるべきJavaScriptのこと」をお伝えしました。
最近のホームページは、見る人に合わせていろいろと情報が変わる動的サイトになっています。
そのなかでも、JavaScriptで動作するWebページをスクレイピングするためには、ブラウザで処理する必要があることがわかりました。
VBAでInternetExplorerを操作できるの?と思われている方もいらっしゃると思います。
はい、それができるんです!
次回の記事で、VBAでInternetExplorerを操作して、Webスクレイピングしていきます。
お楽しみに!
連載目次:JavaScriptで動作するWebページを色々な言語でスクレイピング
Webスクレイピングしていて、値が取得できないということはありませんか?
そんな時は、Webサイトの表示にJavaScriptを利用しているからです。
本連載では、色々な言語でその対応をご紹介します!
- GASやVBAでスクレイピングができない理由として考えるべきJavaScriptのこと
- VBAでIEを操作してJavaScriptで動作するWebページをスクレイピング
- GASでJavaScriptで動作するWebページをスクレイピングするPhantomJsとは
- GASでPhantomJSを利用してWebページをスクレイピング
- GASでスクレイピングしたデータからmatchメソッドと正規表現を使って目的の値を取得
- PythonでPhantomJs Cloudを利用してWebページをスクレイピング
- PythonとPhantomJs CloudでスクレイピングしたデータをBeautifulSoupで解析