美文网首页
python使用正则将QQ聊天记录转换为Html

python使用正则将QQ聊天记录转换为Html

作者: 产品经理不是经理啊 | 来源:发表于2019-10-11 22:32 被阅读0次

    一、需求

    提取qq聊天记录中的所有图片并保存在指定的文件夹。

    二、知识要点

    • 大文件的流式匹配。re[1]、mmap[2]
    • 命令行进度条。tqdm[3]
    • 构建简单的命令行工具。click[4]
    • python多进程异步IO。multiprocessing.apply_async()[5]

    三、全部代码

    import re
    import os
    import sys
    import mmap
    import base64
    import  multiprocessing as m
    import click
    from tqdm import tqdm
    
    
    def  get_images(mhtFilepath):
        with open(mhtFilepath,'r+') as f:   #打开模式必须为读写模式
            data = mmap.mmap(f.fileno(), 0) #内存映射,防止文件过大,内存溢出
            pattern=re.compile(rb'Content-Type:image/(.*?)\r\nContent-Transfer-Encoding.*?\r\nContent-Location:{(.*?)}.dat\r\n\r\n(.*?)\r\n\r\n',re.DOTALL) #正则匹配图片后缀名、base64编码的图片数据、文件ID
            return pattern.finditer(data)   #finditer返回迭代对象,findall返回list(内存占用太大)
    
    def write_to_image(imgOutputpath,strFileName,strContent,strSuffix):
        with open(imgOutputpath + "/" + strFileName + "." + strSuffix,'wb') as f:
            f.write(base64.b64decode(strContent))
    
    @click.command()
    @click.argument('mht_filename', type=click.Path(exists=True))
    @click.option('--image_output_path','-o','image_output_path', prompt=True,help='image output path')
    def get_images_from_mht(mht_filename,image_output_path):
        '''从mht文件中提取图片'''
        if not os.path.exists(image_output_path):
            click.echo('{}路径不存在'.format(image_output_path))
            code=input('是否创建文件?(Y/N)')
            if code.strip().lower()=='y':
                try:
                    os.makedirs(image_output_path)
                except Exception as e:
                    click.echo('无法创建目录',e)
                    sys.exit(0)
            else:
                sys.exit(0)
        else:
            cwd=os.getcwd()
            try:
                os.makedirs(cwd+'/images')
            except Exception as e:
                click.echo('无法创建目录',e)
                sys.exit(0)
        click.echo('正在从{}提取图片,请稍后...'.format(click.format_filename(mht_filename)))
        pool = m.Pool(processes=m.cpu_count())  #创建进程池
        d = get_images(mht_filename)
        for item in tqdm(d,unit='张'):
            suffix = item.group(1).decode('utf-8')
            filename = item.group(2).decode('utf-8')
            content = item.group(3).decode('utf-8')
            pool.apply_async(write_to_image, (image_output_path,filename,content,suffix,)) #异步io写入文件,节省时间
        pool.close()
        pool.join()
        click.echo('提取完成,图片保存在{}'.format(click.format_filename(image_output_path)))
    
    
    if __name__=='__main__':
        get_images_from_mht()
    

    四、使用方法

    第三步代码保存到getImgsFromMht.py,在cmd或powershell中执行python getImgsFromMht.py --help
    获取图片:python getImgsFromMht.py -d 图片保存路径 mht文件路径

    五、参考资料


    1. Python中re的match、search、findall、finditer区别

    2. 来源于"Stack Overflow"----how-do-i-re-search-or-re-match-on-a-whole-file-without-reading-it-all-into-memory

    3. tqdm参考文档

    4. click参考文档

    5. 多进程copy文件

    相关文章

      网友评论

          本文标题:python使用正则将QQ聊天记录转换为Html

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