一 提取pdf方法介绍

任务是用python提取PDF里的表格文件到excel里面去。做为一个 学了一个周python的人来说当然像尝试一下看能不能做到,事实证明是可以的只是可能代码有点烂。。。。。。
样本大概是这样的

首先网上查一下用python处理pdf文件的方法,感觉处理pdf文件的有好多种方法,各自有各自的特点,印象最深的是转成html文件的pdf2htmlEX,和提取文本的pdfminer,还有最后用的Tabula。分别介绍一下记录。

  • pdf2htmlEX
    做这个的时候不怎么了解html,而且也有人曾经尝试过似乎挺麻烦的,所以就没有去尝试。
  • pdfminer
    pdfminer功能非常的强大,可以转好多东西,用得到直接阅读官方文档,由于解析PDF是一件非常耗时和内存的工作,因此PDFMiner使用了一种称作lazy parsing的策略,只在需要的时候才去解析,以减少时间和内存的使用。
    解析结构图大概是这样的

    PDFParser:从一个文件中获取数据
    PDFDocument:保存获取的数据,和PDFParser是相互关联的
    PDFPageInterpreter处理页面内容
    PDFDevice将其翻译成你需要的格式
    PDFResourceManager用于存储共享资源,如字体或图像。
    这个模块是通过页面布局解析出来的,解析出来大概如下

    一句话概括:把相应布局的内容保存到不同的地方如上图布局,用到的什么就调用相应的函数读取。
    尝试过用这个方法提取表格但是挺麻烦的,网上别人给的思路是可以用识别线条的方法提取表格内容,如果能写出来应该效果挺不错的,时间有限加上网上也没用教程可以参考,都是不推荐用这个模块提取表格的,就没有继续尝试。提取文本内容应该很合适。
  • Tabula
    专门用来提取pdf里的表格的,支持导出csv.,excel文件
    提取出来一个页面如果有两个表格会放到一个list里,每个表格一个元素。一个表格一个dataframe结构的文件,所以需要配合pandas模块使用。

二 练习项目介绍

好久之前写了,一些细节忘记了,不过当时注释的很清楚直接上代码,也是怕哪天电脑突然死机代码没了。。。换个地儿存。。。这个模块提取的效率是真的慢。。。。。听说可以调Java的程序提取效率快三倍但是没学Java也就没有去了解,以后还用得到应该可以去了解一下。。。。。。

# -*- coding: utf-8 -*-import os
import gc
from PyPDF2.pdf import PdfFileReader
from tabula import read_pdf
import pandas as pd
from openpyxl import load_workbook, Workbook
import datetimedef data_process2(dataframe2):"""三步:删除只有一个非空或者全空的列从第一列开始往后合并直到遇到只有第一列不为空或者全不为空则处理下一步遇到只有第一行不为空则检查接下来的第三行如果一样情况则接下来三行合并成一行"""#此循环处理只有一个非空或者全空列的情况,防止影响下面的处理k = 0while True:if dataframe2.notnull().sum(axis=0)[k] <= 1:print("%d空列\n", k, dataframe2.notnull()[k])if k+1 == dataframe2.columns.size:dataframe2 = dataframe2.iloc[0:, :k]else:dataframe_left = dataframe2.iloc[0:, :k]dataframe_right = dataframe2.iloc[0:, k + 1:]dataframe2 = pd.concat([dataframe_left, dataframe_right], axis=1, ignore_index=True)k = k-1if k >= dataframe2.columns.size-1:breakk = k+1i = 0t = 0print("去掉空列后\n", dataframe2)#空字符代替NaN防止NaN和其他合并时全为空dataframe2_copy = dataframe2.fillna('', inplace=False)#此循环处理表头while True:if i == 0:if dataframe2.notnull().sum(axis=1)[0] == dataframe2.columns.size:breakif dataframe2.notnull().sum(axis=1)[0] == 1 and dataframe2.notnull().iat[0, 0]:breaki = i + 1else:if dataframe2.notnull().sum(axis=1)[i] == dataframe2.columns.size:t = t+1breakif dataframe2.notnull().sum(axis=1)[i] == 1 and dataframe2.notnull().iat[i, 0]:t = t+1breakdataframe2_copy.iloc[t] = dataframe2_copy.iloc[t] + dataframe2_copy.iloc[i]i = i+1if i >= len(dataframe2):t = t + 1breakprint("处理表头中\n", dataframe2_copy)#去掉空行,并且重新索引dataframe2_copy.dropna(axis=0, how='all', inplace=True)dataframe2_copy = dataframe2_copy.reset_index(drop=True)#次循环处理表里的数据while i < len(dataframe2):if i+2 >= len(dataframe2):for p in range(len(dataframe2)-i):dataframe2_copy.iloc[t] = dataframe2_copy.iloc[i+p]t = t+1breakelif dataframe2.notnull().sum(axis=1)[i] == 1 and dataframe2.notnull().iat[i, 0]:if dataframe2.notnull().sum(axis=1)[i+2] == 1 and dataframe2.notnull().iat[i+2, 0]:dataframe2_copy.iloc[t] = dataframe2_copy.iloc[i] + dataframe2_copy.iloc[i+1] + dataframe2_copy.iloc[i+2]i = i+3elif i+4 < len(dataframe2):if dataframe2.notnull().sum(axis=1)[i + 1] == 1 and dataframe2.notnull().sum(axis=1)[i + 3] == 1 and dataframe2.notnull().sum(axis=1)[i + 4] == 1 and dataframe2.notnull().iat[i+1, 0] and dataframe2.notnull().iat[i+3, 0] and dataframe2.notnull().iat[i+4, 0]:dataframe2_copy.iloc[t] = dataframe2_copy.iloc[i] + dataframe2_copy.iloc[i + 1] + dataframe2_copy.iloc[i + 2] + dataframe2_copy.iloc[i + 3] + dataframe2_copy.iloc[i + 4]i = i + 5else:dataframe2_copy.iloc[t] = dataframe2_copy.iloc[i]i = i + 1else:dataframe2_copy.iloc[t] = dataframe2_copy.iloc[i]i = i + 1else:dataframe2_copy.iloc[t] = dataframe2_copy.iloc[i]i = i+1t = t+1print("一个表的数据\n",dataframe2_copy)return dataframe2_copy.iloc[:t]def data_process1(dataframes):"""根据两个空格拆分列数据合并适用于数据均为str类型表格如果非str型合并后为空数据丢失"""dataframes.fillna('', inplace=True)print("处理前数据:\n", dataframes)n = 0while True:try:dataframes[n].str.split('  ', expand=True)#一列全是非str  passdataframes[n] = dataframes[n].astype('str')#处理有一部分为非str情况,防止数据丢失over_data = dataframes[n].str.split('  ', expand=True)over_data.fillna('', inplace=True)except:print("遇到非str型的列   pass")n = n+1if n >= dataframes.columns.size:breakelse:continueprint("重叠的列:\n", over_data)if n-1 < 0:dataframe_right = dataframes.iloc[0:, n + 1:]dataframes = pd.concat([over_data, dataframe_right], axis=1, ignore_index=True)elif n+1 > dataframes.columns.size:dataframe_left = dataframes.iloc[0:, :n]dataframes = pd.concat([dataframe_left, over_data], axis=1, ignore_index=True)else:dataframe_left = dataframes.iloc[0:, :n]dataframe_right = dataframes.iloc[0:, n+1:]dataframes = pd.concat([dataframe_left, over_data, dataframe_right], axis=1, ignore_index=True)n = n + over_data.columns.sizeif n >= dataframes.columns.size:breakprint("处理后数据\n:", dataframes)return dataframesdef getCashflowAggregation(dataframe1):passdef pdf_to_xlsx(folder):"""提取文件夹的PDF里表格数据对数据做初步整理对每个dataframe识别提取想要的数据保存到相应的sheet里,输出同名xlsx格式文件"""files = os.listdir(folder)#遍历文件夹,找出PDF文件pdfFile = [f for f in files if f.endswith(".pdf")]for pdfFiles in pdfFile:#建立一个和PDF同名的xlsx文件pdfPath = os.path.join(folder, pdfFiles)xlsPath = pdfPath[:-3] + "xlsx"#建立Workbook然后和所要保存的数据表格连接,之后每次保存都会保存到不同的Sheet中Workbook(xlsPath)book = Workbook()book.save(filename=xlsPath)#获取PDF的页数pdf = PdfFileReader(open(pdfPath, "rb"))page_counts = pdf.getNumPages()dataframe2 = pd.DataFrame()#遍历PDF每一页,提取出表格数据for page in range(1, page_counts+1):try:pf = read_pdf(pdfPath, encoding='gbk', multiple_tables=True,pages = page)if len(pf) != 0:for t in range(len(pf)):dataframe1 = pf[t]dataframe1 = data_process2(dataframe1)#处理表头dataframe1 = data_process1(dataframe1)#按空格拆分合并项#CashflowAggregation = getCashflowAggregation(dataframe1)#列数相同的表格合并,并且删除重复项并保存if dataframe2.empty:dataframe2 = dataframe1elif dataframe1.columns.size == dataframe2.columns.size:dataframe2 = pd.concat([dataframe2,dataframe1],ignore_index=True)#删除重复项会影响池分布的匹配提取,但是可以很好的处理静动态池和现金流归集#dataframe2.drop_duplicates(keep="first", inplace=True)#在原来的数据里删除重复项print(dataframe2)else:print("列数:", dataframe1.columns.size)print(dataframe2)#保存在不同的工作簿writer = pd.ExcelWriter(xlsPath, engin='openpyxl')book = load_workbook(writer.path)writer.book = bookdataframe2.to_excel(writer, sheet_name='shet')writer.close()dataframe2 = dataframe1del(pf)gc.collect()except:gc.collect()print("Error Pass")continue#保存最后的数据表格到另一个工作表里writer = pd.ExcelWriter(xlsPath, engin='openpyxl')book = load_workbook(writer.path)writer.book = bookdataframe2.to_excel(writer, sheet_name='shet')writer.close()star_time = datetime.datetime.now()
pdf_to_xlsx("D:\\2018暑假\\新建文件夹")
stop_time = datetime.datetime.now()
print("程序运行时间:", stop_time-star_time)

用python提取PDF表格内容保存到excel相关推荐

  1. python 发票信息提取_Python提取发票内容保存到Excel.md

    Python提取PDF发票内容保存到Excel --- 摘要:这篇文章介绍如何把发票内容提取出来保存到Excel中.文章分为两个部分,第一部分程序用法,第二部分介绍代码. --- 作者:yooongc ...

  2. e语言mysql怎么放在超级列表框,『易语言怎么将超级列表框的内容保存到excel或者Access!』...

    易语言把编辑框里的内容保存到Excel里 个人建议: 1.建议选据库成你要的修改.添加.查作 2.添加一个列表框,可以轻松直观的处理数据 3.如果有使用Excel的需求,那就弄一个导出按键 这样才能是 ...

  3. python提取pdf表格数据并保存到excel中

    pdfplumber操作pdf文件 python开源库pdfplumber,可以较为方便地获取pdf的各种信息,包含pdf的基本信息(作者.创建时间.修改时间-)及表格.文本.图片等信息,基本可以满足 ...

  4. Python提取PDF表格及文本!(附源码)

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理. PS:如有需要Python学习资料的小伙伴可以点击下方链接自行获取 Python免费学习资料 ...

  5. python提取pdf文件内容_如何用Python批量提取PDF文本内容?

    本文为你展示,如何用Python把许多PDF文件的文本内容批量提取出来,并且整理存储到数据框中,以便于后续的数据分析. 问题 最近,读者们在后台的留言,愈发五花八门了. 写了几篇关于自然语言处理的文章 ...

  6. python 提取pdf表格_用Python提取pdf文件中的表格数据

    本文作者:杨慧琳 本文编辑:周聪聪 技术总编:张学人有问题,不要怕!访问 http://www.wuhanstring.com/uploads/5_aboutus/爬虫俱乐部-用户问题登记表.docx ...

  7. 【Python自动化】PDF表格内容转化为Excel

    基于OCR技术的PDF表格提取脚本 基于百度飞桨paddleocr技术 苏格拉底两千多年前就警醒过我们:人啊,认识你自己,这句不仅被作为神谕镌刻在雅典阿波罗神庙外的柱子上,也成了一众哲学家从未停止探讨 ...

  8. python提取pdf表格数据_Python骚操作,提取pdf文件中的表格数据!

    在实际研究中,我们经常需要获取大量数据,而这些数据很大一部分以pdf表格的形式呈现,如公司年报.发行上市公告等.面对如此多的数据表格,采用手工复制黏贴的方式显然并不可取.那么如何才能高效提取出pdf文 ...

  9. 实用脚本!Python 提取 PDF 指定内容生成新文件!

    很多时候,我们并不会预知希望提取的页号,而是希望将包含指定内容的页面提取合并为新PDF,本文就以两个真实需求为例进行讲解. 01 需求描述 数据是一份有286页的上市公司公开年报PDF,大致如下 现在 ...

最新文章

  1. 文献学习(part52)--基于泛岭估计对岭估计过度压缩的改进方法
  2. MySQL8.0 - 新特性 - 安全及权限相关改进
  3. shell 脚本中 while 只执行一次
  4. trang.jar转换xml到Javabean
  5. linux服务器跟踪命令,Linux下使用strace命令来跟踪.htaccess的使用
  6. Numpy Scalars(标量)
  7. PaddleOCR服务器端部署C++ cpu或者gpu进行预测
  8. Bash shell中的位置参数$#,$*,$@,$0,$1,$2...及特殊参数$?,$-等的含义 1
  9. 叫醒你的是闹钟,还是梦想?
  10. 如何使用JDK提供的帮助文档
  11. Vue表情包输入组件
  12. 听说QQ扫码登录很难,办了它
  13. 搜索引擎广告和信息流广告有什么区别?
  14. 【万字解读】数据可视化图表使用场景大全 !
  15. clickhouse的傻瓜式安装和基础入门
  16. 2020中国高校薪资排行出炉!来看看你们学校排名吧~
  17. ActiveSync
  18. 理解实时操作系统与裸机的区别
  19. StoneDB 为何敢称业界唯一开源的 MySQL 原生 HTAP 数据库
  20. 世界上最难得九宫格???你敢挑战吗?

热门文章

  1. v+=e不等于v=v+e
  2. [BZOJ4044]-Virus synthesis-回文自动姬+DP
  3. python的roc曲线与阈值_浅谈ROC曲线的最佳阈值如何选取
  4. OKTA demo 推荐第一种
  5. sscom5.13.1串口调试助手百度云下载免费
  6. 聚势成峰 驭梦未来 壹号珠宝、华礼宴分享交流会在重庆燃情绽放
  7. MySQL报错:Data truncated for column 的原因之一
  8. 教你轻松解除word文档保护(转)
  9. iOS使用讯飞语音-语音识别(最新版)
  10. Cheat 安装与使用