7

自由なテキスト、リスト、表、見出しなどを含む HTML ページを構文解析するにはどうすればよいでしょうか?

たとえば、このウィキペディアのページを見てください。ある/ある:

Python NLTKをいじった後、これらのさまざまなコーパス アノテーション メソッドをすべてテストしたいと思います ( 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 を試してみたい!

4

4 に答える 4

1

すべての HTML を取り除いてフラットなドキュメントを生成しているように聞こえますが、ばらばらな部分がくっついているためにパーサーを混乱させます。あなたは XML の経験があるので、入力を単純な XML 構造にマッピングして、部分を分離することをお勧めします。必要に応じて単純にすることができますが、おそらくいくつかの情報を保持したいと思うでしょう。たとえば、タイトルやセクションの見出しなどにフラグを立てると便利な場合があります。チャンクを個別に保持する実行可能な XML ツリーを取得したら、XMLCorpusReaderそれを NLTK ユニバースにインポートするために使用します。

于 2012-07-01T16:33:01.143 に答える
1

分析していた XML ドキュメントに固有のルールを作成する必要がありました。

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

XML を使用する場合は、新しいマッピングをタグとして表すことができます。元。<h1> から <フレーズ>; <li> から <paragraph>; <td> から <token>

プレーン テキストで作業したい場合は、POS や EOS のラベル付けと同様に、一連の文字 (例: [PHRASESTART][PHRASEEND]) としてマッピングを表すことができます。

于 2013-12-06T23:44:28.933 に答える
0

HTML ページから記事を抽出することを目的としたpython-gooseなどのツールを使用できます。

それ以外の場合は、次のような良い結果をもたらす小さなプログラムを作成しました。

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)
于 2016-11-10T20:38:56.107 に答える