
タイトルの通り、AngularJSを採用しているサイトをウェブスクレイピングしたいです。
環境は
Golang
"github.com/PuerkitoBio/goquery"
を使います。
(Goやgoqueryでなくても構わないのですが。)
サイトに対してGETリクエストをし、返ってきたレスポンスボディ(HTML)を使ってスクレイピングしたいです
普通に
doc, _ := goquery.NewDocumentFromResponse(レスポンス)
とすると、AngularJSで生成される要素が取れません
AngularJSを採用しているサイトに対するウェブスクレイピングは不可能なんでしょうか
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答2件
0
ベストアンサー
あー…これはHTMLとは何なのか、普段使っているWebブラウザ(IEやChrome等)が何をやってるか知らなきゃ解決出来ませんわ
超ざっくりと流れを説明すると、
HTMLというのはSGML系に属するテキストファイル
。
オンラインでドキュメントを管理する為に、見出しは<h1>xxx</h1>
のxxxの部分に書いてくださいねというルール決めを行って作られたのがHTML。
ここ重要、HTMLはただのテキストファイル
。
Chrome等のブラウザは、Webサーバにアクセスして、このHTMLというテキストファイルをダウンロードしてくる。
このHTMLを隅々まで解析して、「CSSが格納されているから表示用にレイアウトを配置しなおすわ」「JavaScriptが格納されているから、HTMLの構造を追加変更削除するわ」といった修正を加えて画面の表示結果に反映している。
これがGolangのライブラリとどう関係するねん?
AngularJSを採用しているサイトをウェブスクレイピングがしたい
"github.com/PuerkitoBio/goquery"
というライブラリの使い方の話に戻るよ。
スクレイピング対象のURLへアクセスすると、HTML(単なるテキストファイル)が払い出される。
その単なるテキストファイル
をライブラリを使って解析して、構造体や文字列として抽出。
でもCSSやJavaScriptはブラウザが便利だから画面表示するユーザーの事を考えて、
勝手に動作している追加機能なんだよ。
HTML自体の文書構造としては関係無いからHTMLの役目からは切り離されてるんだよ。
えっ、JavaScriptでHTMLの文書構造が変更されたら?
"github.com/PuerkitoBio/goquery"
でどうやって抽出するの?
できる訳無いでしょ!JavaScriptまで解析し始めたらChromeの全てをまるっと取り込んだ数百MBの超大作になるよ!!
だから単なるテキストファイル
を解析するライブラリ以上の事は出来ない。
AngularJSにかぎらず、JavaScriptでHTMLの構造を組み替えるページ全て全滅というわけ。
これがスクレイピングの2大弱点の一つなんだよ。
まずその会社が公開しているWebAPIやRSSで代用できないか、
公開してないなら諦める事を視野にいれろと言われるのはこのためだね。
どうしてもJavaScriptで書き換わるページをスクレイピングしたい
可能
Golangとは関係ない話になるけどね。
そもそもブラウザしかHTMLとJavaScriptを連動して動かせない以上、
マクロか何かで、本物のブラウザを操って無理やり動かすやり方が必要になるわけだね。
Chromeはwebkitという有名レンダリングエンジンを搭載していて、
webkit自体はオープンソースで誰でも入手可能。
スクレイピング目的だから画面表示要らないよね、このwebkitにマクロを読み込ませて外から操って結果を抜き出すというPhantomJS(2011~)というブラウザが登場した。
ただこのPhantomJS、依存パッケージのインストールが面倒だったり、日本語が豆腐に文字化けしたりとすこぶる使い勝手が悪かった。
ももそのままChromeやFireFox使いたいよ!!
その願いがそれらのブラウザの製作者に通じて、ChromeやFireFoxではスクリプトで動かすヘッドレスモードが実装されたのだ。
これが最近の話。
ここで悲報、Golangにはこのヘッドレスブラウザを操るライブラリがない。
見当たらなかっただけで、探せば見つかるかもしれないし、技術力と情熱さえあれば自作出来るレベルだろうけどね。
この辺のジャンルはNode.jsが強くて、他の言語は遅れてるってのが現状だね。
というわけで、JavaScriptのコードでヘッドレスブラウザを動作させて結果を標準出力に吐き出して、
Golangからシステムコマンドnode hogehoge.js
を実行して、結果を標準出力越しに受け取り、処理を継続する流れになる。
それ
"github.com/PuerkitoBio/goquery"
を使う意味ある?
もうないね、ヘッドレスブラウザがJavaScript(Node.js)のコードしか受け付けない以上、
全部Node.jsでやってしまえばいいわけだし…
ただまぁ、AngularJSで作用後のHTMLのbodyタグ直下を全て受け取って、
まるっとgoqueryの変換機に投げ込んでやればgoqueryで継続して使えそうではあるね。
予めハマリポイントを推測しておくならば、
ブラウザがHTMLを受け取ってからどのくらいの時間を掛けて、AngularJSを解析してHTMLの文章を書き換えるのか分からないよね。
だから、ヘッドレスブラウザに搭載されている「○○を待つ」という機能を活用することになる。
私はPhantomJSしか触ってないけど、適当に10秒間待つ事もできるし、
<div class"hoge">xxx</div>
が生成されるまで待つという具体的で確実な手法も存在する。
めんどくさい、他の方法ないの?
AngularJSで決まりきった情報に書き換えるようなページはそうない。
大抵「Ajax通信を飛ばして、追加情報をJSON形式で、それを解析してHTMLを書き換えている」
後はもう分かるね?
Chromeならデベロッパーツール(F12)のネットタブを開いて、Ajax通信の接続先を覚えておけばいい。
後はGolangでHTTP通信でJSONを直接とりに行ってパースすれば解決。
スクレイピングなんて要らなかったんや。
投稿2017/11/12 04:14
総合スコア21400
0
不可能ではありません.
ご存知とは思いますが,AngularJSなどのJavaScriptフレームワークは手元で実行される必要があります.
そのため,ブラウザやそれに相当する機能を持つツールが必要となります.
Headless Chromeなどが該当します.
ヘッドレス Chrome ことはじめ
投稿2017/11/11 22:36
総合スコア1159
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。


あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2017/11/12 04:26
2017/11/12 04:37
退会済みユーザー
2017/11/12 04:45 編集
2017/11/12 05:13
退会済みユーザー
2017/11/12 06:23 編集