美文网首页Pythonpython自学scrapy
Python从网页文件获取纯文本并拆分文本文件

Python从网页文件获取纯文本并拆分文本文件

作者: blade_he | 来源:发表于2018-06-01 15:25 被阅读49次

    从HTML文件获取纯文本

    通过BeautifulSoup获取纯文本

    之前是通过BeautifulSoup (bs4)获取纯文本的,简单演示如下:

    from bs4 import BeautifulSoup
    
    htmfile = 'myweb.htm'
    html = open(htmfile, 'r', encoding='utf-8')
    htmlpage = html.read()
    soup = BeautifulSoup(htmlpage.strip(), 'html.parser')
    print(soup.text)
    

    但是这样做的问题在于,其控制文本的格式或许与浏览器端显示的不一样
    浏览器端显示的格式:


    2018-06-01 14_36_17-Document.png

    bs4抓取的文本格式如下:


    2018-06-01 15_06_04-.png
    为什么会这样呢?
    因为在html源码中,存在这样的换行:
    2018-06-01 15_09_30-Document.png

    可以理解为bs4仅仅将html中的tag什么的去除了,但是并没有考虑格式与浏览器显示一致。

    经过一番搜索,终于找到相应的方案

    通过HTMLParser获取纯文本

    HTMLParser是可以无视tag中的换行符的,如同浏览器一样,只要在tag中的文本,如<p>等,无论是否换行,在浏览器都是显示为一行。
    安装:

    pip install HTMLParser
    

    但是安装之后运行,或许会提示找不到markupbase module的错误。
    可以去如下地址下载:markupbase
    然后将_markupbase.py更名为markupbase.py,并拷贝到python安装路径的:Lib\site-packages目录下,如: D:\python36\Lib\site-packages
    具体的代码如下,我是将其单独写在一个python代码文件中,方便重用:

    from re import sub
    from sys import stderr
    #need download https://pypi.org/project/micropython-_markupbase/3.3.3-1/#files,
    #  and copy _markupbase.py to \Lib\site-packages, then rename it to markupbase.py
    # this library make html content to be right format
    from HTMLParser import HTMLParser
    from traceback import print_exc
    from bs4 import BeautifulSoup
    
    class _DeHTMLParser(HTMLParser):
        def __init__(self):
            HTMLParser.__init__(self)
            self.__text = []
    
        def handle_data(self, data):
            text = data.strip()
            if len(text) > 0:
                text = sub('[ \t\r\n]+', ' ', text)
                self.__text.append(text + ' ')
    
        def handle_starttag(self, tag, attrs):
            if tag == 'p':
                self.__text.append('\n\n')
            elif tag == 'br':
                self.__text.append('\n')
            elif tag == 'div':
                self.__text.append('\n')
    
        def handle_startendtag(self, tag, attrs):
            if tag == 'br':
                self.__text.append('\n\n')
    
        def text(self):
            return ''.join(self.__text).strip()
    
    def dehtml(text):
        try:
            parser = _DeHTMLParser()
            parser.feed(text)
            parser.close()
            return parser.text()
        except:
            print_exc(file=stderr)
            #If invoke exception, then return text by beautifulsoup
            soup = BeautifulSoup(text, 'html.parser')
            return soup.text
    

    之后提取的文本就是符合我们格式要求的:


    2018-06-01 15_19_08-htmltotext [D__Blade_MorningStar.Demo_github_htmltotext] - ..._txt_159343589_0cd.png

    主程序代码

    包括:解压htm压缩包,提取纯文本,拆分文本文件
    拆分文本文件,我是每500行就拆为一个小的文本文件
    但是,考虑到避免将一个完整的段落文字拆到几个文本文件中,加入了最后一行必须以句号:.为结尾(相对英文文件文本)如果是汉语,可以加入结尾是否是汉字句号:。的判断。
    压缩文件相对于程序代码路径:./htmzip
    解压的htm文件相对于程序代码路径:./htm
    txt文件相对于程序代码路径:./txt
    完整主程序代码:

    import os
    import parsehtmltext
    import zipfile
    
    def startjob():
        zipfilelist = getfilelist('./htmzip', '.zip')
        count = 1
        for filepath in zipfilelist:
            (filefolder, zipfilename) = os.path.split(filepath)
            print('handle the %d file: %s start' % (count, zipfilename))
            unzipfolder = './htm/%s' % (zipfilename)
            unzip(filepath, unzipfolder)
            htmlfilelist = getfilelist(unzipfolder, '.htm')
            if len(htmlfilelist) > 0:
                txtfilelist = splithtmltotxt(htmlfilelist[0],
                                             './txt/%s' % (zipfilename))
                print(txtfilelist)
            count += 1
    
    def getfilelist(folderpath, extension):
        filelist = []
        for (root, dirs, files) in os.walk(folderpath):
            for filename in files:
                if filename.lower().endswith(extension.lower()):
                    filepath = os.path.join(root, filename).replace('\\','/')
                    filelist.append(filepath)
        return filelist
    
    def splithtmltotxt(htmfile, txtfolder):
        html = open(htmfile, 'r', encoding='utf-8')
        htmlpage = html.read()
        wholetextlines = parsehtmltext.dehtml(htmlpage).split('\n')
        if len(wholetextlines) == 1 and len(wholetextlines[0].strip()) > 100:
            wholetextlines = wholetextlines[0].split('.')
        testblock = []
    
        if os.path.isdir(txtfolder):
            pass
        else:
            os.mkdir(txtfolder)
        txtfilelist = []
        #整体计数器
        count = 1
        #用于单文本文件行数的计数器
        eachcount = 0
        #文本文件数量的计数器
        txtfilecount = 1
        totalcount = len(wholetextlines)
        # print(wholetextlines)
        # print(totalcount)
        for line in wholetextlines:
            if line.split():
                testblock.append(line.strip() + '\n')
                eachcount += 1
            # print('each count is %d, count is %d, total count is %d' % (eachcount, count, totalcount))
            if (eachcount >= 500
                and (line.endswith('\n') or line.strip().endswith('.')))\
                    or count == totalcount:
                txtfilename = '%s/%d.txt' % (txtfolder, txtfilecount)
                with open(txtfilename, 'w', encoding='utf-8') as f:
                    f.writelines(testblock)
                # print('save txt file: %s'% txtfilename)
                txtfilelist.append(txtfilename)
                #reset single counter
                testblock = []
                eachcount = 0
                txtfilecount += 1
            count += 1
        return txtfilelist
    
    def unzip(sourcefile, unzipfolder):
        with zipfile.ZipFile(sourcefile) as zip_file:
            if os.path.isdir(unzipfolder):
                pass
            else:
                os.mkdir(unzipfolder)
            for names in zip_file.namelist():
                zip_file.extract(names, unzipfolder)
    
    if __name__ == '__main__':
        startjob()
    

    相关文章

      网友评论

      本文标题:Python从网页文件获取纯文本并拆分文本文件

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