<返回更多

使用Python进行文本分析-将PDF文件多进程批量处理为csv文件

2023-11-14  微信公众号  PaperCodeTips
加入收藏

在文本分析的过程中,将原始数据转换为TXT文件非常关键,主要出于以下几个方面的考虑:

使用Python进行文本分析-将PDF文件多进程批量处理为csv文件

1.格式简单与统一:

2. 便于文本预处理:

3.兼容性:

4.节省资源:

5.便于文本挖掘和模式识别:

6.可读性和可检查性:

7.数据清洗:

将原始数据转换为TXT文件是实现有效和准确文本分析的一个基本步骤,它帮助简化和标准化文本分析流程,从而提高分析的效率和质量。以下代码可以用来将pdf文件转换为txt文件。

pdf2txt.py

#!/usr/bin/env Python/ target=_blank class=infotextkey>Python  # 该行命令告诉操作系统使用 Python 解释器执行此文件
import sys  # 导入sys模块,用于处理与Python解释器和运行时环境有关的操作
from pdfminer.pdfdocument import PDFDocument  # 从pdfminer模块导入PDFDocument类,用于表示PDF文档
from pdfminer.pdfparser import PDFParser  # 从pdfminer模块导入PDFParser类,用于解析PDF文档
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter  # 从pdfminer模块导入资源管理和页面解释类
from pdfminer.pdfdevice import PDFDevice, TagExtractor  # 从pdfminer模块导入PDF设备和标签提取器类
from pdfminer.pdfpage import PDFPage  # 从pdfminer模块导入PDFPage类,用于表示PDF页面
from pdfminer.converter import XMLConverter, htmlConverter, TextConverter  # 从pdfminer模块导入转换器类,用于将PDF转换为其他格式
from pdfminer.cmapdb import CMapDB  # 从pdfminer模块导入字符映射数据库类
from pdfminer.layout import LAParams  # 从pdfminer模块导入布局分析参数类
from pdfminer.image import ImageWriter  # 从pdfminer模块导入图像写入类

# 定义主函数,argv是一个包含命令行参数的列表
def mAIn(argv):
    import getopt  # 导入getopt模块,用于解析命令行参数
    # 定义一个显示用法的内部函数
    def usage():
        print ('usage: %s [-P password] [-o output] [-t text|html|xml|tag]'
               ' [-O output_dir] [-c encoding] [-s scale] [-R rotation]'
               ' [-Y normal|loose|exact] [-p pagenos] [-m maxpages]'
               ' [-S] [-C] [-n] [-A] [-V] [-M char_margin] [-L line_margin]'
               ' [-W word_margin] [-F boxes_flow] [-d] input.pdf ...' % argv[0])
        return 100  # 返回一个错误代码
    try:
        # 使用getopt解析命令行参数
        (opts, args) = getopt.getopt(argv[1:], 'dP:o:t:O:c:s:R:Y:p:m:SCnAVM:W:L:F:')
    except getopt.GetoptError:
        return usage()  # 如果解析失败,则显示用法并退出
    if not args: return usage()  # 如果没有提供非选项参数(例如输入文件),则显示用法并退出
    # 初始化一些变量
    debug = 0  # 调试级别
    password = b''  # PDF密码
    pagenos = set()  # 要处理的页码集
    maxpages = 0  # 最大页数
    outfile = None  # 输出文件名
    outtype = None  # 输出类型
    imagewriter = None  # 图像写入对象
    rotation = 0  # 旋转角度
    stripcontrol = False  # 是否剥离控制字符
    layoutmode = 'normal'  # 布局模式
    encoding = 'utf-8'  # 编码方式
    pageno = 1  # 页面号
    scale = 1  # 缩放因子
    caching = True  # 是否缓存
    showpageno = True  # 是否显示页面号
    laparams = LAParams()  # 布局分析参数对象
    for (k, v) in opts:  # 遍历选项和值
        if k == '-d': debug += 1  # 设置调试级别
        elif k == '-P': password = v.encode('ascii')  # 设置密码
        elif k == '-o': outfile = v  # 设置输出文件名
        elif k == '-t': outtype = v  # 设置输出类型
        elif k == '-O': imagewriter = ImageWriter(v)  # 创建图像写入对象
        elif k == '-c': encoding = v  # 设置编码方式
        elif k == '-s': scale = float(v)  # 设置缩放因子
        elif k == '-R': rotation = int(v)  # 设置旋转角度
        elif k == '-Y': layoutmode = v  # 设置布局模式
        elif k == '-p': pagenos.update(int(x)-1 for x in v.split(','))  # 更新页码集
        elif k == '-m': maxpages = int(v)  # 设置最大页数
        elif k == '-S': stripcontrol = True  # 启用剥离控制字符
        elif k == '-C': caching = False  # 禁用缓存
        elif k == '-n': laparams = None  # 禁用布局分析参数
        elif k == '-A': laparams.all_texts = True  # 启用所有文本选项
        elif k == '-V': laparams.detect_vertical = True  # 启用垂直检测选项
        elif k == '-M': laparams.char_margin = float(v)  # 设置字符边距
        elif k == '-W': laparams.word_margin = float(v)  # 设置单词边距
        elif k == '-L': laparams.line_margin = float(v)  # 设置行边距
        elif k == '-F': laparams.boxes_flow = float(v)  # 设置框流
    # 设置调试级别
    PDFDocument.debug = debug
    PDFParser.debug = debug
    CMapDB.debug = debug
    PDFPageInterpreter.debug = debug
    # 创建PDF资源管理器对象
    rsrcmgr = PDFResourceManager(caching=caching)
    # 根据输出类型和选项创建相应的PDF设备对象
    if not outtype:
        outtype = 'text'  # 默认为文本输出
        if outfile:
            if outfile.endswith('.htm') or outfile.endswith('.html'):
                outtype = 'html'  # 如果输出文件名以.htm或.html结尾,则设置为html输出
            elif outfile.endswith('.xml'):
                outtype = 'xml'  # 如果输出文件名以.xml结尾,则设置为xml输出
            elif outfile.endswith('.tag'):
                outtype = 'tag'  # 如果输出文件名以.tag结尾,则设置为tag输出
            elif outtype == 'tag':
        device = TagExtractor(rsrcmgr, outfp)  # 如果输出类型为'tag',则创建TagExtractor对象
    else:
        return usage()  # 如果不识别的输出类型,则显示用法并退出

    for fname in args:  # 遍历所有输入文件名
        with open(fname, 'rb') as fp:  # 以二进制读模式打开文件
            interpreter = PDFPageInterpreter(rsrcmgr, device)  # 创建PDF页面解释器对象
            # 遍历PDF页面,获取页面对象
            for page in PDFPage.get_pages(fp, pagenos,
                                          maxpages=maxpages, password=password,
                                          caching=caching, check_extractable=True):
                page.rotate = (page.rotate+rotation) % 360  # 设置页面旋转角度
                interpreter.process_page(page)  # 处理每个页面

    device.close()  # 关闭设备对象,释放资源
    outfp.close()  # 关闭输出文件,释放资源
    return  # 从主函数返回

# 检查此模块是否作为主模块运行
if __name__ == '__main__':
    sys.exit(main(sys.argv))  # 如果是,则调用main函数,并使用命令行参数列表作为参数

convertPDF.py

#!/usr/bin/env python3
"""
Script to convert PDFs to text files.

"""

import  unicodedata, os, pdf2txt, datetime

import multiprocessing
def convertPDFToText(i, ID, newDir, fileNamePDF):
    print('Trying to convert: ' + str(i) + ', ' + ID)  # 输出正在尝试转换的文件信息
    try:
        pdf2txt.main(['-o', newDir + '/' + ID + '.txt', fileNamePDF])  # 调用pdf2txt.main来转换PDF为文本
        print('Successfully converted: ' + ID)  # 转换成功时的输出
    except Exception as e:
        print('Failed to convert: ' + ID + f', Error: {e}')  # 转换失败时的输出

def process_pdfs(pdf_list):
    with multiprocessing.Pool(20) as pool:  # 创建一个包含20个进程的进程池
        pool.starmap(convertPDFToText, pdf_list)  # 使用starmap来并行处理pdf_list中的每个元素,每个元素都是一个元组,它将被解包为convertPDFToText的参数

if __name__ == '__main__':

    directory = '../../Data/PDF/work'
    os.chdir(directory)  # 更改当前工作目录至PDF文件目录

    # 指定保存转换后文件的目录
    newDir = '../TXT/work'
    # os.makedirs(newDir)  # 创建新目录(如果需要的话)
    print('Placing converted files in: ' + newDir)  # 输出转换后文件将被放置的目录

    pdf_list = []  # 创建一个空列表,用于保存将传递给convertPDFToText的参数元组
    i = 0  # 初始化计数器
    for fileNamePDF in os.listdir('./'):  # 遍历当前目录中的所有文件
        i += 1  # 计数器递增
        if fileNamePDF.find(".pdf") == -1:  # 如果文件不是PDF,跳过
            continue

        ID = fileNamePDF[:-4]  # 从文件名中获取ID(去掉.pdf后缀)
        if os.path.isfile('../TXT/' + ID + '.txt'):  # 如果已经存在对应的文本文件,跳过
            continue

        pdf_list.Append((i, ID, newDir, fileNamePDF))  # 将参数元组添加到pdf_list中

    process_pdfs(pdf_list)  # 调用process_pdfs函数,传递pdf_list以并行处理PDF文件
关键词:Python      点击(17)
声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多Python相关>>>