当前位置:   article > 正文

使用python进行文本分析-将PDF文件多进程批量处理为csv文件_python pdf表格转csv

python pdf表格转csv

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

1.格式简单与统一

  • • TXT文件是一种简单的文本格式,只包含纯文本信息,不包含任何格式或样式信息。这种简单和统一的格式有助于减少在文本分析过程中可能出现的混淆或误解。

  • • 其他格式的文档,如PDF或Word文档,可能包含图像、表格和其他非文本元素,还可能包含复杂的格式和样式,这些都可能干扰文本分析的过程。

2.便于文本预处理

  • • 文本分析通常需要对文本数据进行预处理,包括分词、去停用词、标准化等。TXT文件的简单结构使得这些预处理任务更容易执行。

  • • 与其他文件格式相比,TXT文件不包含任何复杂的格式或元数据,这有助于简化预处理步骤,减少可能出现的错误和问题。

3. 兼容性

  • • 大多数文本分析和自然语言处理(NLP)工具都能够直接处理TXT文件。将原始数据转换为TXT文件可以确保与这些工具的兼容性,从而简化分析流程。

  • • TXT文件是一种通用的文件格式,可以在不同的操作系统和软件环境中轻松处理,而不需要特定的转换或适配器。

4. 节省资源

  • • TXT文件通常比其他文件格式更小,这有助于节省存储空间和提高处理速度。较小的文件大小也意味着需要较少的计算资源来处理文本数据,从而提高分析效率。

  • • 简单的文本格式也意味着在处理时CPU和内存的消耗较低,这对于大规模文本分析任务来说是非常重要的。

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

  • • 纯文本格式使得使用正则表达式和其他文本挖掘技术来识别和提取文本中的模式变得更为容易和直接。

  • • 纯文本数据也便于实现各种文本分析技术,如情感分析、主题建模和实体识别等。

6.可读性和可检查性

  • • 人类可以直接读取和理解TXT文件,这对于检查、调试和理解文本分析的结果非常重要。

7. 数据清洗

  • • TXT文件的简单性使得更容易识别和处理缺失值、错误和其他数据质量问题,从而保证文本分析的准确性和可靠性。

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

pdf2txt.py

#!/usr/bin/env 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函数,并使用命令行参数列表作为参数
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106

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文件
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

关于Python的技术储备

如果你是准备学习Python或者正在学习,下面这些你应该能用得上:

① Python所有方向的学习路线图,清楚各个方向要学什么东西
② 100多节Python课程视频,涵盖必备基础、爬虫和数据分析
③ 100多个Python实战案例,学习不再是只会理论
④ 华为出品独家Python漫画教程,手机也能学习
⑤历年互联网企业Python面试真题,复习时非常方便

文末有领取方式哦

一、Python所有方向的学习路线

Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、Python课程视频

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。
在这里插入图片描述

三、Python实战案例

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

四、Python漫画教程

用通俗易懂的漫画,来教你学习Python,让你更容易记住,并且不会枯燥乏味。
在这里插入图片描述
在这里插入图片描述

五、互联网企业面试真题

我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
在这里插入图片描述
在这里插入图片描述
这份完整版的Python全套学习资料已经上传CSDN,朋友们如果需要也可以扫描下方csdn官方二维码或者点击主页和文章下方的微信卡片获取领取方式,【保证100%免费】
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/51326
推荐阅读
相关标签
  

闽ICP备14008679号