python正则将qq聊天记录转换为html

一、需求

提取qq聊天记录中的所有图片并保存在指定的文件夹,并将聊天记录转换为html。

二、知识要点

  • 大文件的流式匹配。re1、mmap2
  • 命令行进度条。tqdm3
  • 构建简单的命令行工具。click4
  • 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文件 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值