2012-06-30 2 views
5

フリーテキスト、リスト、表、見出しなどを含むHTMLページを文章に解析するにはどうすればよいですか?HTMLを文章に解析する - テーブル/リスト/見出し/などを扱う方法?

たとえば、this wikipedia pageとします。 /ありさ:

が、私は、これらの異なるのすべてをテストしたいですコーパスの注釈方法(http://nltk.googlecode.com/svn/trunk/doc/book/ch11.html#deciding-which-layers-of-annotation-to-include):

  • ワードトークン:テキストの正書法は、そのトークンを明白に識別しません。トークン化され、正規化されたバージョンは、従来の正書法のバージョンに加えて、非常に便利なリソースである可能性があります。
  • 文の分割:第3章で見たように、文のセグメンテーションは、見た目よりも難しくなる可能性があります。したがって、一部のコーパスは、文のセグメンテーションをマークするために明示的な注釈を使用します。
  • 段落分割:段落と他の構造要素(見出し、章など)に明示的に注釈を付けることができます。
  • 音声の部分:文書内の各単語の構文カテゴリ。
  • 構文構造:文の構成構造を示すツリー構造。
  • シャローセマンティクス:名前付きエンティティおよびコアリファレンスアノテーション、意味ロールラベル。
  • 対話と談話:対話行為タグ、修辞構造

あなたは文章の中に文書を分割したら、それはとても簡単そうです。しかし、ウィキペディアのページからHTMLのようなものをどうやって分解するのですか?私はHTML/XMLパーサーを使ってツリーをトラバースすることに非常に精通しています。プレーンテキストを取得するためにHTMLタグを取り除いてみましたが、HTMLが削除された後に句読点がないため、NLTKはテーブルセル、またはリストさえ正しく表示されます。

NLPを使用してその内容を解析するためのベストプラクティスまたは戦略がありますか?あるいは、その個々のページに固有のパーサを手動で書く必要がありますか?

ちょうど正しい方向にいくつかのポインタを探して、本当にこのNLTKを試してみたい!

+0

ストリップされたテキストにPunkt(NLTKで実装されています)を使用してみてください。 – dmh

+1

私の非公式の観察は、パーザは一般的に表示テキストを扱い、表現することに悪いことです(実行中の散文とは対照的です)。あなたが良い解決策を見いだした場合、ここでフォローアップしてください! – tripleee

答えて

1

すべてのHTMLを取り除いてフラットな文書を生成しているように思えます。フラットな文書を作成すると、ゆるい部分が一緒に張り付いているので、パーサが混乱します。あなたはXMLに精通しているので、入力を単純なXML構造にマッピングして、断片を分けておくことをお勧めします。あなたはそれをあなたが望むだけ簡単にすることができますが、おそらくあなたはいくつかの情報を保持したいでしょう。たとえば、タイトル、セクション見出しなどにフラグを立てると便利です。チャンクを別々に保持する実行可能なXMLツリーがある場合は、XMLCorpusReaderを使用してそれをNLTKユニバースにインポートします。

1

私が分析していたXMLドキュメントに固有のルールを記述しなければなりませんでした。

私がしたのは、htmlタグをセグメントにマッピングすることでした。このマッピングは、いくつかのドキュメント/ページを調べ、htmlタグが表すものを判断することに基づいていました。 Ex。 <h1>はフレーズセグメントです。 <li>は段落です。 <td>はトークンです

XMLで作業する場合は、新しいマッピングをタグとして表すことができます。 Ex。 <h1 >~<フレーズ>; <l>~<段落>; <TD> <にプレーンテキストで作業する場合は、文字の集合としてマッピングを表すことができ>

トークン(例:[PHRASESTART] [PHRASEEND])、ちょうどPOSやEOSラベルのような。

0

python-gooseなどのツールを使用して、HTMLページから記事を抽出することができます。答え

from html5lib import parse 


with open('page.html') as f: 
    doc = parse(f.read(), treebuilder='lxml', namespaceHTMLElements=False) 

html = doc.getroot() 
body = html.xpath('//body')[0] 


def sanitize(element): 
    """Retrieve all the text contained in an element as a single line of 
    text. This must be executed only on blocks that have only inlines 
    as children 
    """ 
    # join all the strings and remove \n 
    out = ' '.join(element.itertext()).replace('\n', ' ') 
    # replace multiple space with a single space 
    out = ' '.join(out.split()) 
    return out 


def parse(element): 
    # those elements can contain other block inside them 
    if element.tag in ['div', 'li', 'a', 'body', 'ul']: 
     if element.text is None or element.text.isspace(): 
      for child in element.getchildren(): 
       yield from parse(child) 
     else: 
      yield sanitize(element) 
    # those elements are "guaranteed" to contains only inlines 
    elif element.tag in ['p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']: 
     yield sanitize(element) 
    else: 
     try: 
      print('> ignored', element.tag) 
     except: 
      pass 


for e in filter(lambda x: len(x) > 80, parse(body)): 
    print(e) 
0

alexisとして、python-gooseは良い選択肢があります。

は、そうでなければ私は、次の小さな良い結果のようなものを与えるプログラムを作りました。

この正確な問題を解決することを目的とした(新しい)ライブラリHTML Sentence Tokenizerもあります。その構文は非常に簡単です。 1行のparsed_sentences = HTMLSentenceTokenizer().feed(example_html_one)では、配列parsed_sentencesに格納されたHTMLページで文章を取得できます。

関連する問題