python实战-pdf文件转txt之类的文本可编辑类型文件
背景:最近刚好需要将一个pdf的内容打出来,这是个比较枯燥的内容,而且pdf里面的文字明显是规范的,所以想写个脚本读取内容,直接复制粘贴。刚好,python的理念就是不重复造*,这样的包自然是有的,这个脚本最主要的包就是pdfminer3k。
1.思路
解析出文档,按页存储进txt文件即可。
2.完整代码
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal, LAParams
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfinterp import PDFTextExtractionNotAllowed
from pdfminer.pdfparser import PDFParser, PDFDocument
def parse_pdf(filepath):
# 创建文件流
fp = open(filepath, 'rb')
# 从文件中获取数据,得到一个解析对象
parser = PDFParser(fp)
# 连接文档和分析器
pdoc = PDFDocument()
parser.set_document(pdoc)
pdoc.set_parser(parser)
# 没有密码,初始化密码为空
pdoc.initialize()
# 检测文档是否提供文本提取
if not pdoc.is_extractable:
raise PDFTextExtractionNotAllowed
else:
# 创建PDf资源管理器对象来管理共享资源,catching=False表示不缓存
pm = PDFResourceManager(caching=False)
# 创建一个PDF参数分析器
laparams = LAParams()
# 创建页面聚合对象
device = PDFPageAggregator(pm, laparams=laparams)
# 创建一个PDF解析器对象
interpreter = PDFPageInterpreter(pm, device)
# 获取page列表
pages = pdoc.get_pages()
# 循环遍历page列表,按页处理
for page in pages:
# 使用页面解释器来读取
interpreter.process_page(page)
# 使用聚合器获取内容
layout = device.get_result()
# 这里layout是一个LTPage对象 里面存放着解析出的各种对象
for item in layout:
# 获取文本
if isinstance(item, LTTextBoxHorizontal):
rst = item.get_text()
with open("test.txt", 'a', encoding='utf-8') as f:
f.write(rst)
if __name__ == '__main__':
filepath = 'test.pdf'
parse_pdf(filepath)
3.错误可能
我在写脚本时遇到了一个问题,这个问题还比较常见。
pdfminer.pdfparser.PDFEncryptionError: Unknown algorithm: param={'CF': {'StdCF': {'AuthEvent': /DocOpen, 'CFM': /V2, 'Length':16}},'Filter':/Standard,'Length':128,'O':b':\r\x18\xf4\xe7i\x1ca\x80\xc9UqX\xdb\xdf\xa4\xaa\x0e\x80J,Xqra\xac\xe8\r\xf1\xb94\xf5','P':-3392,'R':4,'StmF':/StdCF,'StrF':/StdCF,'U':b'\xbc7/j\xc4\xc2)\xe6g\xebX\xc2\x81\x10n\x97\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', 'V': 4}
这段错误的原因主要是默认现在的pdf文件就算你打开就能看,但是其实还是设置了一个空密码,而pdfminer3k是不认的,它认为就算需要密码,这里可以随便找个在线网站处理一下空密码解锁pdf文件。
其实这样的空密码加密表面上对读者没有影响,但是其实是为了防止复制粘贴而已。
4.源文件
5. 运行结果