几种网页文本提取的方式及其优缺点

2017-05-27  本文已影响1054人  如烟花非花

0.背景说明

前段时间cert举办的技术对抗赛上,提供了一个数据样本,全部是html文件。正好有个同事正在研究机器学习的文本分类,就琢磨的看看能不能提取到一些有用的样本信息。因为要提取文本,就想到需要一个好的html文本提取函数来进行。

通过上网查询,发现目前采用的方式有如下几种:

  1. Python-goose
  2. BeautifulSoup
  3. html2text
  4. nltk
  5. plaintext

下面就以下几种方式做一个初步的探索

1. 简单实验

  1. 首先是Python-goose,goose这个工原来是用Java写的文章提取工具,后来用python进行了重写,就形成了Python-goose。它不仅提取出文章的主体,同时提取出所有元信息以及图片等信息,支持中文网页。更多介绍看这里:点击这里传送
    话不多说,上一小段代码(注意这里只提取文本和标题):
def extract_text_by_goose(doc_text):
    title, text = '', ''
    g = Goose({'parser_class': 'lxml', 'stopwords_class': StopWordsChinese})
    try:
        article = g.extract(raw_html=doc_text)
    except Exception as error:
        print error
        pass
    else:
        title = article.title
        text = article.cleaned_text
    return title, text

经过尝试,发现googse解析的信息不错,但是存在一个问题是,对于某些网站(图片、视频资源比较多)解析速度非常慢,甚至达到了不能容忍的地步。

  1. 其次是BeautifulSoup,这也是目前最主流和最大众的方法。
def extract_text_by_bs(doc_text):
    """提取html页面的所有文本信息。
    参考:
    http://stackoverflow.com/questions/328356/extracting-text-from-html-file-using-python
    """
    title, text = '', ''
    soup = BeautifulSoup(doc_text, 'lxml')
    try:
        for script in soup(["script", "style"]):
            script.extract()
    except Exception as error:
        print error
        pass
    else:
        try:
            # get text
            title = soup.title.string
        except Exception as error:
            print error
            pass
        text = soup.get_text()
        lines = (line.strip() for line in text.splitlines())
        chunks = (phrase.strip() for line in lines for phrase in line.split("  "))
        text = ' '.join(chunk for chunk in chunks if chunk)
    return title, text

进过尝试,这个方法解析的信息不错,并且速度还是比较快的。目前分析采用了这种方式。

3.html2text,这个是一个github项目点击这里传送。这个项目还是比较简单易用的,而且可以传入多种参数进行组合调整。

import html2text
def extract_text_by_h2t(doc_text):
    h = html2text.HTML2Text()
    h.ignore_links = True
    h.bypass_tables = False
    h.unicode_snob = False
    text = h.handle(doc_text)
    return text

经过尝试,这个方法对中文编码混乱的情况容错性没有BeautifulSoup好,会产生乱码的行为(可能是研究不到位)。

4.nltk,一个python的自然语言处理库,可以很方便的完成很多自然语言处理(NLP)的任务,包括分词、词性标注、命名实体识别(NER)及句法分析。非常知名,这里就不做过多描述了。

from nltk.tokenize import word_tokenize, sent_tokenize

def extract_text_by_nltk(doc_text):
    tokens = [word for sent in sent_tokenize(doc_text) for word in word_tokenize(sent)]
    return filter(lambda word: word not in ',-', tokens)

这是 stackoverflow上面人介绍到的一种方式,这个方法用的很普遍,这里也做了尝试,短期快速上手难度大,并且中文这方面需要一些其他库。时间上研究的比较少,有用过的可以指导一下。

5.pattern.web点击这里传送,这个库看文档说明很强大,包含了解析和爬取等等功能。

from pattern.web import plaintext
def extract_text_by_pattern(doc_text):
    text = plaintext(doc_text)
    return text

同第3个方法经过尝试,这个方法对中文编码混乱的情况容错性没有BeautifulSoup好,不过比html2text好一些,会产生乱码的行为(可能是研究不到位)。

3. 总结

通过上述实验,实际上,如果是进行简单的文本样本分析,无外乎希望两点:

  1. 容错性好
  2. 速度快
    所以,实际上研究表明还是希望BeautifulSoup这种方式,但是实际生产中,可能上诉的几种库还有更高级的用法,所以也值得研究。另外,在网上看到一种用正则表达式去提取样本的方法,也是满足目前需求的,速度也还可以。

PS

本文只是一个简单的研究,并没有经过系统专业的测试,可能提到的观点有错误,还望能交流指出。

上一篇下一篇

猜你喜欢

热点阅读