1

HTMLページを解析してそこからデータを抽出するJavaアプリケーションがあります。現在、特定のWebページの読み方に関するテンプレートまたは指示として機能するクラスがあります。アプリケーションは、異なる形式のいくつかの異なるサイトから読み取る必要があります。フォーマットの種類ごとに新しいテンプレートクラスを作成するのではなく、どのデータとどこを抽出するかについての指示を提供する付属のXMLファイル(または別のドキュメント)を読み取れるようにしたいと思います。

これを行う方法についてインターネットを検索しようとしましたが、正しい質問をしたり、正しいキーワードを使用したりしていないと思います。

このソリューションでは、テンプレートとしてXMLを使用する必要はありませんが、それが私の最初の考えでした。

誰かが私を正しい方向に向けることができますか?

4

3 に答える 3

2

xmlでテンプレートを使用するのではなく、読み取りている各サイトの目的のデータにマップするxpath式を保持できます。次に、スクレイピングするページが変更されると、そのサイトのxpath式を更新できます。

于 2012-11-08T23:28:06.887 に答える
2

は、単一のソースから対象のデータを抽出するために使用Extractorします。ExtractionInstructions抽出したデータは、後でエクストラクタから取得できます。

このハイレベルなデザインでは

  • ソース:同じデータを抽出する各ページ
  • Extractor:単一のソースで実行される抽出ごとに1つのインスタンス
  • ExtractionInstructions:単一のソースからデータを抽出する方法を明確に説明する一連の命令。
    • 命令を明確に指定することができます
      • タグIDおよび/または
      • CSS3セレクターおよび/またはを使用する
      • xpathなど。
    • 上記のすべてを組み合わせて(責任の連鎖パターン)連鎖させることで、成功率を高めることができます。1種類の抽出を使用してデータが見つからない場合は、データが見つかるか、手順がなくなるまで、他のオプションを試すことができます)。

これらの抽象化を構築するためのベースライブラリとしてJSoupを使用することをお勧めします。

于 2012-11-08T23:37:55.893 に答える
0

私は実際に以前にこのようなことをしたことがありますが、それはかなり複雑でした。基本的に、抽出プラグインをパラメーター化できるプラグインシステム(うんざりするほどMavenのようなもの)を作成しました。

これは、DSLとしてSpringBeanXMLを使用して行うことができます。

<bean id="strategy1"  class="absolute.class.name">
</bean>

<bean id="extractorExecutor" class="class.to.extractorExecutor">
   <property name="strategies">
    <list>
        <item ref="strategy1" />
        <item ref="strategy2" />
     </list>
    </property> 
</bean>

エクストラクタは基本的に、次のようなインターフェイスを実装する一連のBeanをループします。

public interface ExtractStrategy {
    /**
     * null means skip this extractor and go to the next one.
     */
    public Extracted extract(String data);
}

抽出機能では、次のことを行います。

for (ExtractorStrategy e : strategies) {
    Extracted ex = e.extract(data);
    if (ex != null) break;
}

Springはこれをリゾルバーチェーンパターンと呼び、一部の人々はこれを戦略パターンと呼びます。

次に、@digitaljoelが言ったようなXPathエクストラクタやRegexExtractorなどを作成できます。戦略を実行したい順序で配置します。

ヒューリスティックが必要なでは、このパターンを常に使用しています。厄介なHTML(他の人からのコメントで言及されている)を抽出するには、JerichoまたはJSoupをお勧めします(この場合、Jericho戦略を作成し、チェーンに追加するだけです)。

于 2012-11-08T23:39:21.503 に答える