web-dev-qa-db-ja.com

AndroidヘッドレスブラウザによるWebスクレイピング

私は1日を費やして、以下を達成するために使用できるライブラリーを研究しました。

  • ビューに結果をレンダリングせずに、バックグラウンドのようにWebページのコンテンツ全体を取得します。
  • Libは、たとえば、最初のHTMLがロードされた後に、追加の結果データをロードするためのajaxリクエストを開始するページをサポートする必要があります。
  • 結果のhtmlから、xpathまたはcssセレクターフォームの要素を取得する必要があります。
  • 将来的には、次のページに移動する必要があるかもしれません(イベントの起動、ボタン/リンクの送信など)。

これが私が成功せずに試したことです:

  • Jsoup:うまく機能しますが、javascript/ajaxのサポートはありません(そのため、ページ全体をロードしません)
  • HttpEntityに組み込まれたAndroid:jsoupと同じjavascript/ajaxの問題
  • HtmlUnit:必要なものは正確に見えますが、数時間後には動作しませんAndroid(他のユーザーは、12MB以上のjarファイルをロードしようとして失敗しました。私自身が完全なソースコードをロードして参照しましたアプレットやJava.awt(HtmlUnitで使用)などがAndroidに存在しないことを確認するためだけに、プロジェクトライブラリとして使用します。
  • Rhino-これは非常に混乱し、Androidでそれを機能させる方法がわからない。
  • Selenium Driver:動作するように見えますが、実際のHTMLをビューに表示しないように、ヘッドレスで実装する簡単な方法はありません。

HtmlUnitが私のソリューションに最も適しているように見えるので、私は本当にHtmlUnitを機能させたいと思っています。私のニーズに適した方法、または少なくとも私が見逃した別のライブラリはありますか?

現在Android Studio 0.1.7を使用しており、必要に応じてEllipseに移動できます。

前もって感謝します!

29
Pierre

2週間後、私は敗北を認め、現時点でうまく機能する回避策を使用しています。

問題:
HTMLUnitをAndroid(または少なくとも私のレベルの専門知識)に移植するのは難しすぎます。これは価値のあるプロジェクトだと確信しています(経験豊富なためにそれほど時間をかけません= Javaプログラマー)。HTMLUnitの担当者にメールを送ったところ、彼らはポートを調べていない、またはどのような取り組みが必要かについてコメントしましたが、そのようなプロジェクトを始めたい人はメッセージを送信するよう提案しましたより多くの開発者を参加させるために彼らのメーリングリストに( http://htmlunit.sourceforge.net/mail-lists.html )。

回避策:
Androidの組み込みWebViewを使用し、WebviewクラスのonPageFinishedメソッドをオーバーライドして、ページが完全に読み込まれた後にすべてのHTMLを取得するJavascriptを挿入しました。 Webviewは、さらにJavascriptアクションの呼び出し、ボタンのクリック、フォームの入力などにも使用できます。

コード:

webView.getSettings().setJavaScriptEnabled(true);
MyJavaScriptInterface jInterface = new MyJavaScriptInterface(context);
webView.addJavascriptInterface(jInterface, "HtmlViewer");

webView.setWebViewClient(new WebViewClient() {

@Override
public void onPageFinished(WebView view, String url) {

   //Load HTML
   webView.loadUrl("javascript:window.HtmlViewer.showHTML
       ('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
}

webView.loadUrl(StartURL);
ParseHtml(jInterface.html);   

public class MyJavaScriptInterface {

    private Context ctx;
    public String html;

    MyJavaScriptInterface(Context ctx) {
        this.ctx = ctx;
    }

    @JavascriptInterface
    public void showHTML(String _html) {
        html = _html;
    }
}
23
Pierre

上記の実装(JavaScriptの挿入)を採用しましたが、それでうまくいきます。私がしているのは、Webビューの可視性を他のUI要素の下に隠すように設定することだけです。セレンについても同じことを考えていました。私はChrome in Python=でSeleniumを使用しましたが、それは素晴らしいですが、ブラウザウィンドウを表示しないのは簡単ではありません。しかし、 Androidでコンポーネントを表示しないようにすることは可能です。

0
bluiska