将HTML解析为句子 - 如何处理表/列表/标题/等?

时间:2012-06-30 20:20:05

标签: python html nlp nltk text-segmentation

如何将包含自由文本,列表,表格,标题等的HTML页面解析为句子?

this wikipedia page为例。有/是:

在搞乱了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 个答案:

答案 0 :(得分:1)

听起来你正在剥离所有HTML并生成一个平面文档,这会使解析器混乱,因为松散的部分会粘在一起。由于您对XML有经验,因此我建议将您的输入映射到一个简单的XML结构,以保持各个部分的分离。您可以根据需要使其变得简单,但也许您希望保留一些信息。例如,标记标题,章节标题等可能是有用的。如果你有一个可行的XML树来保持块的分离,可以使用XMLCorpusReader将它导入到NLTK Universe中。

答案 1 :(得分:1)

我必须编写特定于我正在分析的XML文档的规则。

我所做的是将html标签映射到细分。此映射基于研究多个文档/页面并确定html标记表示的内容。 防爆。 < H1>是一个短语片段; <李>是段落; < TD>是代币

如果要使用XML,可以将新映射表示为标记。 防爆。 < H1>到< phrase&gt ;; <李>到<段&gt ;; < TD>到< token>

如果您想处理纯文本,可以将映射表示为一组字符(例如[PHRASESTART] [PHRASEEND]),就像POS或EOS标签一样。

答案 2 :(得分: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)

答案 3 :(得分:0)

alexis回答时,python-goose可能是个不错的选择。

还有HTML Sentence Tokenizer,一个(新)图书馆,旨在解决这个问题。它的语法非常简单。在一行parsed_sentences中,您可以获取存储在数组df.isnull().sum().sum() 中的HTML页面中的句子。