前言
项目的需求中曾经提到能够处理多重类型的文档,虽然不太实用,但是还是要想办法实现;
遇到的问题和之前类似:正文和代码不能用用一种方法同时提取。
提取正文
需要用到pdfminer库:
由于PDF文件有如此大和复杂的结构,完整解析PDF文件很费时费力;
大多数PDF工作中,很多模块是不需要加进来的;
因此 PDFMiner采用了一个懒惰分析的策略,就是只分析所需要的部分;
解析时候,至少需要2个核心类,PDFParser 和 PDFDocument,这两个模块配合其他模块来使用。
大致流程:
1.PDFParser 从文件中获取数据
2.PDFDocument 存储文档数据结构到内存中
3.PDFPageInterpreter 解析page内容
4.PDFDevice 把解析到的内容转化为你需要的东西
5.PDFResourceManager存储共享资源,例如字体或图片
code:
def get_pdf_text(in_path, out_path):
'''解析PDF文本,并保存到TXT文件中'''
fp = open(in_path,'rb')
#用文件对象创建一个PDF文档分析器
parser = PDFParser(fp)
#创建一个PDF文档
doc = PDFDocument()
#连接分析器,与文档对象
parser.set_document(doc)
doc.set_parser(parser)
#提供初始化密码,如果没有密码,就创建一个空的字符串
doc.initialize()
#检测文档是否提供txt转换,不提供就忽略
if not doc.is_extractable:
raise PDFTextExtractionNotAllowed
else:
#创建PDF,资源管理器,来共享资源
rsrcmgr = PDFResourceManager()
#创建一个PDF设备对象
laparams = LAParams()
device = PDFPageAggregator(rsrcmgr,laparams=laparams)
#创建一个PDF解释其对象
interpreter = PDFPageInterpreter(rsrcmgr,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:
if(isinstance(x,LTTextBoxHorizontal)):
with open(out_path,'a') as f:
results = x.get_text()
f.write(results +"\n")
提取图片
需要用到pymupdf库。
code:
def get_pdf_picture(in_path, out_folder_path):
doc = fitz.open(in_path)
for i in range(len(doc)):
imglist = doc.getPageImageList(i)
for j, img in enumerate(imglist):
xref = img[0]
pix = fitz.Pixmap(doc, xref) # 利用库函数
out_name = get_file_name(in_path)
print(out_name)
if pix.n - pix.alpha < 4: # 能储存为PNG格式
pix.writePNG(out_folder_path+out_name+"%s-%s.png" % (i+1, j+1))
else: # 需要进行转化
pix0 = fitz.Pixmap(fitz.csRGB, pix)
pix0.writePNG(out_folder_path+out_name+"%s-%s.png" % (i+1, j+1))
pix0 = None # 释放资源
pix = None