安装
# pip install pdfminer
pip install pdfminer3k
pip install pdfminer.six 安装这个引入的内容不会报错
若安装不成功,可以试试下面方法
首先下载pdfminer3k:https://pypi.python.org/pypi/pdfminer3k;然后安装pdfminer,将下载好的pdfminer3k解压到D:或其他合适的盘符,通过win+r 打开运行窗口,输入cmd;输入D:切换到D盘,cd pdfminer3k(pdf解压的文件夹),输入setup.py install安装软件。
解析pdf文件用到的类
PDFParser:从一个文件中获取数据
PDFDocument:保存获取的数据,和PDFParser是相互关联的
PDFPageInterpreter处理页面内容
PDFDevice将其翻译成你需要的格式
PDFResourceManager用于存储共享资源,如字体或图像。
PDF转Word功能所需的依赖包如下:
PDFParser(文档分析器)
PDFDocument(文档对象)
PDFResourceManager(资源管理器)
PDFPageInterpreter(解释器)
PDFPageAggregator(聚合器)
LAParams(参数分析器)
整体思路
构造文档对象,解析文档对象,提取所需内容
image
构造文档对象
image
PDFMiner的类之间的关系图:
这里写图片描述
Layout布局分析返回的PDF文档中的每个页面LTPage对象。这个对象和页内包含的子对象,形成一个树结构。如图所示:
这里写图片描述
LTPage :表示整个页。可能会含有LTTextBox,LTFigure,LTImage,LTRect,LTCurve和LTLine子对象。
LTTextBox:表示一组文本块可能包含在一个矩形区域。注意此box是由几何分析中创建,并且不一定表示该文本的一个逻辑边界。它包含LTTextLine对象的列表。使用 get_text()方法返回文本内容。
LTTextLine :包含表示单个文本行LTChar对象的列表。字符对齐要么水平或垂直,取决于文本的写入模式。使用get_text()方法返回文本内容。
LTAnno:在文本中字母实际上被表示为Unicode字符串。需要注意的是,虽然一个LTChar对象具有实际边界,LTAnno对象没有,因为这些是“虚拟”的字符,根据两个字符间的关系(例如,一个空格)由布局分析后插入。
LTImage:表示一个图像对象。嵌入式图像可以是JPEG或其它格式,但是目前PDFMiner没有放置太多精力在图形对象。
LTLine:代表一条直线。可用于分离文本或附图。
LTRect:表示矩形。可用于框架的另一图片或数字。
LTCurve:表示一个通用的Bezier曲线
代码实操
方法1
# -*- coding:utf-8 -*-
import time,os.path,requests,re
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LAParams,LTTextBoxHorizontal,LTImage,LTCurve,LTFigure
from pdfminer.pdfpage import PDFTextExtractionNotAllowed,PDFPage
from pdfminer.pdfparser import PDFParser
from pdfminer.pdfdocument import PDFDocument
from docx import Document
document = Document()
”’
pip install pdfminer3k
pip install pdfminer.six 安装这个引入的内容不会报错
”’
class CPdf2TxtManager():
def changePdfToText(self, filePath):
# 以二进制读模式打开
file = open(path, ‘rb’)
#用文件对象来创建一个pdf文档分析器
praser = PDFParser(file)
# 创建一个PDF文档对象存储文档结构,提供密码初始化,没有就不用传该参数
doc = PDFDocument(praser, password=”)
##检查文件是否允许文本提取
if not doc.is_extractable:
raise PDFTextExtractionNotAllowed
# 创建PDf 资源管理器 来管理共享资源,#caching = False不缓存
rsrcmgr = PDFResourceManager(caching = False)
# 创建一个PDF设备对象
laparams = LAParams()
# 创建一个PDF页面聚合对象
device = PDFPageAggregator(rsrcmgr, laparams=laparams)
# 创建一个PDF解析器对象
interpreter = PDFPageInterpreter(rsrcmgr, device)
# 获得文档的目录(纲要),文档没有纲要会报错
#PDF文档没有目录时会报:raise PDFNoOutlines pdfminer.pdfdocument.PDFNoOutlines
# print(doc.get_outlines())
# 获取page列表
print(PDFPage.get_pages(doc))
# 用来计数页面,图片,曲线,figure,水平文本框等对象的数量
num_page, num_image, num_curve, num_figure, num_TextBoxHorizontal = 0, 0, 0, 0, 0
# 循环遍历列表,每次处理一个page的内容
for page in PDFPage.create_pages(doc):
num_page += 1 # 页面增一
# 利用解释器的process_page()方法解析读取单独页数
interpreter.process_page(page)
# 接受该页面的LTPage对象
layout = device.get_result()
fileNames = os.path.splitext(filePath)
# 这里layout是一个LTPage对象 里面存放着 这个page解析出的各种对象
# 一般包括LTTextBox, LTFigure, LTImage, LTTextBoxHorizontal 等等
for x in layout:
if hasattr(x, “get_text”) or isinstance(x, LTTextBoxHorizontal):
with open(fileNames[0] + ‘.txt’,’a+’) as f:
# 将’\xa0’替换成u’ ‘空格,这个\xa0就是&nbps空格
results = x.get_text().replace(u’\xa0′, u’ ‘)
f.write(results + ‘\n’)
document.add_paragraph(
results, style=’ListBullet’ # 添加段落,样式为unordered list类型
)
document.save(‘./data/demo1.docx’) # 保存这个文档
# 如果x是水平文本对象的话
if isinstance(x, LTTextBoxHorizontal):
num_TextBoxHorizontal += 1 # 水平文本框对象增一
if isinstance(x, LTImage): # 图片对象
num_image += 1
if isinstance(x, LTCurve): # 曲线对象
num_curve += 1
if isinstance(x, LTFigure): # figure对象
num_figure += 1
print(‘对象数量:%s,页面数:%s,图片数:%s,曲线数:%s,’
‘水平文本框:%s,’%(num_figure,num_page,num_image,num_curve,num_TextBoxHorizontal))
if __name__ == ‘__main__’:
path = ‘./data/13.pdf’
pdf2TxtManager = CPdf2TxtManager()
pdf2TxtManager.changePdfToText(path)
print(‘ok,解析pdf结束!’)
方法2
# -*- coding: utf-8 -*-
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
import requests,os,re
try:#python3
from io import StringIO
from urllib.request import urlopen
except:#python2
from urllib import urlopen
from cStringIO import StringIO
”’
pip install pdfminer3k
pip install pdfminer.six 安装这个引入的内容不会报错
”’
def convert_pdf_to_txt(path,save_name):
if debug:
# 加载内存的方式
retstr = StringIO()
fp = StringIO(path)
else:
#读取文件的方式
retstr = open(path, ‘rb’)
fp = open(path, ‘rb’)
# 创建一个PDF资源管理器对象来存储共享资源,caching = False不缓存
rsrcmgr = PDFResourceManager(caching=False)
# 创建一个PDF设备对象
laparams = LAParams()
device = TextConverter(rsrcmgr, retstr, codec=’utf-8′, laparams=laparams)
# 创建一个PDF解析器对象
interpreter = PDFPageInterpreter(rsrcmgr, device)
for page in PDFPage.get_pages(fp, pagenos=set(), maxpages=0, password=”,caching=True, check_extractable=True):
interpreter.process_page(page)
fp.close()#关闭输入流
device.close()#关闭输出流
str = retstr.getvalue()
retstr.close()
with open(“%s”%save_name,”w”) as f:
for i in str:
f.write(i)
print(“%s Writing Succeed!”%save_name)
if __name__ == ‘__main__’:
try:
debug=False # True
if debug:
#这种方式暂时还有问题
url=”http://pythonscraping.com/pages/warandpeace/chapter1.pdf”
pdf_file = urlopen(url).read() # 也可以换成本地pdf文件,用open rb模式打开
# pdf_file = requests.get(url).content
# 加载内存的方式
convert_pdf_to_txt(pdf_file, “./data/12.txt”)
else:
#读取文件的方式
convert_pdf_to_txt(‘./data/12.pdf’,”./data/12.txt”)
except Exception as e:
import traceback
ex_msg = ‘{exception}’.format(exception=traceback.format_exc())
print(ex_msg)
批量提取
# -*- coding:utf-8 -*-
import os,re
from pdfminer.pdfinterp import PDFResourceManager,PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
”’
pip install pdfminer3k
pip install pdfminer.six 安装这个引入的内容不会报错
”’
#将一个pdf转换成txt
def pdfTotxt(filepath,outpath):
try:
fp = open(filepath, ‘rb’)
outfp=open(outpath,’w’)
#创建一个PDF资源管理器对象来存储共享资源,caching = False不缓存
rsrcmgr = PDFResourceManager(caching = False)
# 创建一个PDF设备对象
laparams = LAParams()
device = TextConverter(rsrcmgr, outfp, codec=’utf-8′, laparams=laparams,imagewriter=None)
#创建一个PDF解析器对象
interpreter = PDFPageInterpreter(rsrcmgr, device)
for page in PDFPage.get_pages(fp, pagenos = set(),maxpages=0,
password=”,caching=False, check_extractable=True):
page.rotate = page.rotate % 360
interpreter.process_page(page)
#关闭输入流
fp.close()
#关闭输出流
device.close()
outfp.flush()
outfp.close()
except Exception as e:
print(“Exception:%s”,e)
#一个文件夹下的所有pdf文档转换成txt
def fileTotxt(fileDir):
files=os.listdir(fileDir)
tarDir=fileDir+’txt’
if not os.path.exists(tarDir):
os.mkdir(tarDir)
replace=re.compile(r’\.pdf’,re.I)
for file in files:
filePath=fileDir+’\\’+file
outPath=tarDir+’\\’+re.sub(replace,”,file)+’.txt’
pdfTotxt(filePath,outPath)
print(“Saved “+outPath)
if __name__ == ‘__main__’:
pdfTotxt(‘000.pdf’, ‘test.txt’)
fileTotxt(‘这里是目录的路径’)
使用pdfminer3K出现WARNING:root:UniGB-UCS2-H问题
问题原因:缺少字体库
解决:
从github下载对应字体库放入,python 库文件 \Lib\site-packages\pdfminer\cmap中。
下载地址:https://github.com/euske/pdfminer/tree/2103e5875ef04cfaf424b25d2fd0dc9535a90714/pdfminer/cmap
从相同下载地址 下载对应的解码文件,放到相同位置,再运行就ok了。
参考:https://blog.csdn.net/xc_zhou/article/details/81009809
https://mp.weixin.qq.com/s/xCKC3cz7jUvrwl4uvMNKTA?spm=a2c6h.12873639.0.0.59a862310MzvtP
https://www.cnblogs.com/wumingxiaoyao/p/8460973.html
https://blog.csdn.net/qq_33570092/article/details/81108428
https://blog.csdn.net/mrlevo520/article/details/52136414