媳妇儿让我给她找一个PDF转word免费工具,找了半天我决定给她写一个出来^-^
之前我媳妇儿让我给她找一个PDF转WORD的免费工具,在网上找了半天发现要不就是收费,要不就是转化的格式混乱。既然网上不能找到好用的免费工具那就直接来写一个吧。人生苦短,我用python。
万能的python肯定应该有关于这个第三方库,百度了一下果不其然——PDFminer3k(如果你用的是python2的话那你应该使用的是pdfminer)。
我们先上代码然后再分析吧。
# -*- coding:utf-8 -*-
#author:菜鸟小白的学习分享
from pdfminer.pdfparser import PDFParser, PDFDocument
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal, LAParams
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed
def parse(DataIO, save_path):
# 用文件对象创建一个PDF文档分析器
parser = PDFParser(DataIO)
# 创建一个PDF文档
doc = PDFDocument()
# 分析器和文档相互连接
parser.set_document(doc)
doc.set_parser(parser)
# 提供初始化密码,没有默认为空
doc.initialize()
# 检查文档是否可以转成TXT,如果不可以就忽略
if not doc.is_extractable:
raise PDFTextExtractionNotAllowed
else:
# 创建PDF资源管理器,来管理共享资源
rsrcmagr = PDFResourceManager()
# 创建一个PDF设备对象
laparams = LAParams()
# 将资源管理器和设备对象聚合
device = PDFPageAggregator(rsrcmagr, laparams=laparams)
# 创建一个PDF解释器对象
interpreter = PDFPageInterpreter(rsrcmagr, device)
# 循环遍历列表,每次处理一个page内容
# doc.get_pages()获取page列表
for page in doc.get_pages():
interpreter.process_page(page)
# 接收该页面的LTPage对象
layout = device.get_result()
# 这里的layout是一个LTPage对象 里面存放着page解析出来的各种对象
# 一般包括LTTextBox,LTFigure,LTImage,LTTextBoxHorizontal等等一些对像
# 想要获取文本就得获取对象的text属性
for x in layout:
try:
if (isinstance(x, LTTextBoxHorizontal)):
with open('%s' % (save_path), 'a') as f:
result = x.get_text()
print(result)
f.write(result + "\n")
except:
print("Failed")
if __name__ == '__main__':
# 解析同一文件夹下的PDF文件,保存到本地doc文件中
with open(r'菜鸟小白.pdf', 'rb') as pdf_html:
parse(pdf_html, r'11.doc')
分析过程
PDF没有WORD、Excel这样简单,可以直接去读取内容,读取PDF文件需要用程序以二进制的方式读取,然后转化成文字。而我们通过pdfminer的转化过程就好比是读取出来具体内容后猜测他们的布局,用于重建文字的结构,但是这个也无法保证100%能够工作。
代码中pdfminer调用的每个函数作用分别为:
DFParser(文档分析器)
PDFDocument(文档对象)
PDFResourceManager(资源管理器)
PDFPageInterpreter(解释器)
PDFPageAggregator(聚合器)
LAParams(参数分析器)
首先我们需要新建一个文档分析器和PDF文档,并且将PDF文档对象和文档分析器关联起来。
# 用文件对象创建一个PDF文档分析器
parser = PDFParser(DataIO)
# 创建一个PDF文档
doc = PDFDocument()
# 分析器和文档相互连接
parser.set_document(doc)
doc.set_parser(parser)
然后我们新建一个资源管理器和新建一个PDF参数对象
# 创建PDF资源管理器,来管理共享资源
rsrcmagr = PDFResourceManager()
# 创建一个PDF设备对象
laparams = LAParams()
然后我们新建一个聚合器,用于接收资源管理器和参数对象;创建一个解释器,接收资源管理器和聚合器。
# 将资源管理器和设备对象聚合
device = PDFPageAggregator(rsrcmagr, laparams=laparams)
# 创建一个PDF解释器对象
interpreter = PDFPageInterpreter(rsrcmagr, device)
然后使用get_pages()去获取所有的页面,用一个for循环遍历每一个页面,使用interperter页面解释器对页面进行逐一聚合,然后调用聚合器的get_result()获取到layout,layout中的每一个内容,只有文本内容才会被提取出来。
# 循环遍历列表,每次处理一个page内容
# doc.get_pages()获取page列表
for page in doc.get_pages():
interpreter.process_page(page)
# 接收该页面的LTPage对象
layout = device.get_result()
# 这里的layout是一个LTPage对象 里面存放着page解析出来的各种对象
# 一般包括LTTextBox,LTFigure,LTImage,LTTextBoxHorizontal等等一些对像
# 想要获取文本就得获取对象的text属性
for x in layout:
try:
if (isinstance(x, LTTextBoxHorizontal)):
with open('%s' % (save_path), 'a') as f:
result = x.get_text()
print(result)
f.write(result + "\n")
except:
print("Failed")
最新实现效果
原始的PDF文档
转化后的word文档
缺陷
当前的代码仅能实现文字的提取,无法提取图片。后面我们再看看能否将图片也一起提取出来,有厉害的小伙伴也可以私信我。
最后我把这个从程序打包成了一个exe文件,只需要将你想要转化的PDF文档和exe文件放在同一个文件夹内就可以双击执行转化了。有需要的小伙伴可以私信菜鸟小白"PDFtoWORD"获取下载链接。
随机推荐
- Android开发学习笔记Intent 一
Inten的概念 1.Intent是Android四大组件直接沟通的桥梁 2.Intent是一种运行时绑定(runtime binding)机制 Intent对象的属性 Itent的种类 Inten过 ...
- Web api配置填坑攻略
最近开始使用web api,开发调试过程还算顺利,现在项目已经发布,网站已经部署,结果浏览过程出现问题(不出问题好像不正常吧……),做个note开始填坑. 1.1号坑 咋一开始就爆出另一个程序正在使用 ...
- Java 多线程基础(八)线程让步
Java 多线程基础(八)线程让步 yield 一.yield 介绍 yield()的作用是让步.它能让当前线程由“运行状态”进入到“就绪状态”,从而让其它具有相同优先级的等待线程获取执行权:但是,并 ...
- swiper 实现滑动解锁
最近项目中有这样一个需求,研究了两种写法一个原生,一个使用框架 原生写法: <!DOCTYPE html> <html> <head> <meta chars ...
- 黎活明8天快速掌握android视频教程--14_把文件存放在SDCard
把文件保存在手机的内部存储空间中 1 首先必须在清单文件中添加权限 <?xml version="1.0" encoding="utf-8"?> & ...
- MapReduce 论文阅读笔记
Abstract MapReduce : programming model 编程模型 an associated implementation for processing and generati ...
- 策略模式、策略模式与Spring的碰撞
策略模式是GoF23种设计模式中比较简单的了,也是常用的设计模式之一,今天我们就来看看策略模式. 实际案例 我工作第三年的时候,重构旅游路线的机票查询模块,旅游路线分为四种情况: 如果A地-B地往返都 ...
- 51单片机入门(补充)1--与C语言的交接
我写完上一个文章,发现我写的还是不够全面,所以,这篇文章将会延续上一个文章的内容,并且再次补充新的东西,如果还有什么地方需要补充,还请各位一一指出,如果你已经学过这些东西,大可以直接跳过,假如说之后有 ...
- Java 从入门到进阶之路(二十八)
在之前的文章我们都是通过 Java 在内存中应用,本章开始我们来看一下 Java 在系统文件(硬盘)上的操作. 系统文件就是我们电脑中的文件,简单来说就是像 Windows 系统中 C D E 等各类 ...
- js的几个小问题
1.存一个有效期为7天的cookie,key = nickname, val = Ace 代码: function setCookie(key,val,expires){ let now=new Da ...