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

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

作者: 如烟花非花 | 来源:发表于2017-05-27 10:44 被阅读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

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

    相关文章

      网友评论

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

          本文链接:https://www.haomeiwen.com/subject/kmgffxtx.html