【Python】 Python 操作PDF文档

Python 操作PDF文档

1、PDF

(便携式文件格式,Portable Document Format)是由Adobe Systems在1993年用于文件交换所发展出的文件格式。 PDF主要由三项技术组成:衍生自PostScript;字型嵌入系统;资料压缩及传输系统。它的优点在于跨平台、能保留文件原有格式(Layout)、开放标准,能免版税(Royalty-free)自由开发PDF相容软体,是一个开放标准,2007年12月成为ISO 32000国际标准。

PDF格式的主要优点:

跨平台性:PDF文件格式与操作系统平台无关,文件不管是在 Windows,Unix还是在苹果公司的 Mac OS 操作系统中都是通用的。

易于阅读:不同平台、不同阅读软件打开不会出错或变形,以及转换成PDF后可以避免其他软件产生的不兼容和字体替换问题,使得文档的灵活性提高。

不易编辑:PDF是板式文档,可防止他人无意中触到键盘修改文件内容。

体积小巧:PDF文件使用了工业标准的压缩算法,通常比 PostScript 文件小,易于传输与储存。

信息丰富:PDF文件格式可以将文字、字型、格式、颜色及独立于设备和分辨率的图形图像等封装在一个文件中。该格式文件还可以包含超文本链接、声音和动态影像等电子信息。

1.1. Python处理PDF常用类库

注意: 2023年,都已经回归到 pypdf 了。 在 Debian 12中,通过下面命令安装:

sudo apt install -y python3-pypdf
大多数组织以PDF形式发布其数据。随着AI的发展,我们需要更多数据来进行预测和分类。 PDF处理有些困难,但是我们可以利用下面的API来简化它。 本文将简要介绍如何使用Python处理PDF。Python处理PDF的第三库也有很多,主要有:

PDFMiner Python中用于PDF处理的库。容易安装,也容易使用。PDFMiner为非程序员提供命令实用程序,为程序员提供API接口。

PyPDF 这个Python PDF库是可扩展的。可以从pdf中提取文本,裁剪,然后将PDF文档与加密和解密功能合并。PyPDF有很多版本。在PyPDF4之前,PyPDF2更加流行。目前都已经合并到 pypdf .

pdfrw 与上面两个提及非常相似。除了这种相似性之外,pdfrw还具有自己的USP(唯一卖点)。pdfrw:一个替代的PDF操作包。Patrick Maupin创建了一个名为pdfrw的软件包,它可以完成许多与PyPDF2相同的工作。除了加密的特殊情况外,本文后面提到PyPDF2的所有操作,pdfrw均可以实现。pdfrw的最大区别在于它与ReportLab软件包集成,因此你可以使用一些或所有预先存在的PDF构建一个新的PDF。

Slate 它是PDFMiner的包装实现。

reportlab Reportlab的特长在于创建PDF文件,尤其是程序动态生成PDF文件的功能十分强大,但是遗憾的是开源版本没有提供读取PDF文件的相关功能。

pyMuPDF MuPDF可以访问PDF,XPS,OpenXPS,CBZ,EPUB和FB2(电子书)格式的文件,并且以其最佳性能和高渲染质量而著称。

tabula-py tabula 是专门用来提取PDF表格数据的,同时支持PDF导出为CSV、Excel格式,但是这工具是用 java 写的,依赖 java7/8。tabula-py 就是对它做了一层 python 的封装

pdfplumber pdfplumber 是按页来处理 pdf 的,可以获得页面的所有文字,并且提供的单独的方法用于提取表格。

1.2. PyPDF

pyPdf,PyPDF2和PyPDF4的历史
最初的pyPdf软件包于2005年发布。pyPdf的最后一个正式版本是在2010年。 大约一年后,一家名为Phasit的公司赞助了一个名为PyPDF2的pyPdf分支。 该代码编写为向后与原始代码兼容,并且用了好多年,效果一直很好,其最后一个版本是在2016年。

有一个名为PyPDF3的软件包简短系列版本,然后该项目被重命名为PyPDF4。 所有这些项目都完全相同,但pyPdf和PyPDF2 +之间的最大区别在于后者版本增加了Python 3支持。 Python 3的原始pyPdf有一个不同的Python 3分支,但是这个分支已经多年没有维护了。

最新版本的PyPDF4支持PyPDF2的大多数功能,但也有部分功能不兼容。

pypdf4主要功能
PyPDF4是一个纯Python PDF库,能够拆分,合并,裁剪和转换PDF文件的页面。它还可以将自定义数据,查看选项和密码添加到PDF文件。它可以从PDF检索文本和元数据,以及将整个文件合并在一起。

提取文档信息(标题,作者等)

逐页拆分文档

逐页合并文档

裁剪页面

将多个页面合并为一个页面

加密和解密PDF文件

2. 读取PDF

接下来使用PyPDF4对PDF文件进行读取,需要注意的是他对英文的支持比较好,如果读取中文就会出现乱码等问题,在后面我们会介绍几个支持读取中文的库。

2.1. 查看PDF信息

可以在自己的电脑上随便找一个PDF文件进行尝试操作。

from pypdf import PdfReader

with open(‘minimal.pdf’,‘rb’) as f:
pdf=PdfReader(f)
information=pdf.metadata
number_of_pages=len(pdf.pages)

txt=f"““Author: {information.author}
Creator: {information.creator}
Producer: {information.producer}
Subject: {information.subject}
Title: {information.title}
Number of pages: {number_of_pages}””"
print(txt)
Author: None
Creator: cairo 1.11.2 (http://cairographics.org)
Producer: cairo 1.11.2 (http://cairographics.org)
Subject: None
Title: None
Number of pages: 1
PdfFileReader是一个具有多种与PDF文件交互的方法的类。 在此示例中,调用了 .getDocumentInfo() ,它将返回DocumentInformation的实例,包含了我们感兴趣的大部分信息。 我们还可以在reader对象上调用 .getNumPages() ,让它返回文档中的页数。

information这个变量具有多个实例属性,可以使用这些属性从文档中获取所需的其余元数据。我们可以打印出该信息并将其返回以备将来使用。

2.2. 读取文本

我们先打开PDF文件,再查看他的页数。

pdffile = open(‘postgis-essential-0423.pdf’,‘rb’)
pdfreader = PdfReader(pdffile)
print(len(pdfreader.pages))
202
我们查看第二页的信息。

page = pdfreader.pages[0]
print(page.extract_text().strip())
第 1章地理空间数据库的发展、技术与标准
回答地理空间问题有很多工具,或桌面应用系统。这种方法虽然功能完备,但不能同时回
答许多问题。此外,这种方法通常无法在一个数据集中有效地管理和操作大量的空间数据集,
也无法使任务自动化。
一旦需要可伸缩性、对大型数据集的支持以及直接输入机制,大多数用户就会使用空间数
据库进行探索。有几个可用的空间数据库软件,一些是专有的,另一些是开源的。 PostGIS 是
一个开源的空间数据库软件,可能是所有空间数据库软件中最容易访问的。
PostGIS 作为扩展运行,为 PostgreSQL 数据库提供空间功能。在这种能力下, PostGIS
允许将空间数据与常规关系型数据一起包含进来。通过构建 PostGIS 提供的核心功能和
PostgreSQL 固有的可扩展性,可以实现新的或增强的功能。
在数据库存储方面,数据库是高级形式,而 PostGIS 赋予其更多的功能。
1.1平面文件、空间数据引擎到空间数据库
在传统的第一代 地理信息系统 (GIS)实现中,所有的 空间数据 都存储在 平面文件( flat
files)中,需要专门的 GIS软件来解释和操作这些数据。这些第一代管理系统旨在满足用
户的需求,其中所有所需的数据都在用户的组织领域中。它们是专为处理 空间数据 而构建的专
有的、独立的系统,应用程序和平面文件之间的耦合性非常高,平面文件里的空间数据没有数
据独立性。
为了提高数据库管理系统( DBMS)对空间数据的管理能力 ,国内外较为流行的主要集中在
“关系型数据库 +空间数据引擎” 、 “扩展对象关系型数据库”两方面。
“关系型数据库+空间数据引擎” 技术方案访问迅速,与 GIS联系紧密,在应用中占有一
定优势。问题是引擎与数据库内核独立,难以利用数据库系统中已有的成熟的管理、访问技术,
在进一步发展上有致命弱点。
“扩展对象空间数据库系统” 技术方案从理论上来看,是最适用于空间数据的表达和管理
的。
3

idx_arr = [0]
for idx, page in enumerate(pdfreader.pages):
cnts = page.extract_text().strip().splitlines()
# print(idx, cnts[0])
if ‘第’ in cnts[0] and ‘章’ in cnts[0]:
print(idx)
print(cnts[0])
if idx != 0:
idx_arr.append(idx)
idx_arr.append(len(pdfreader.pages))

print(idx_arr)
0
第 1章地理空间数据库的发展、技术与标准
12
第 2章创建您的第一个空间数据库
22
第 3章 PostGIS 的数据读写与转换
36
第 4章 PostGIS 中的几何图形:文本表达的输入与输出
50
第 5章几何图形的简单性与有效性
64
第 6章合成和分解几何图形
78
第 7章空间数据坐标系统与投影
84
第 8章空间度量与测度
88
第 9章使用 Geography
96
第 10章一元几何图形操作
102
第 11章空间关系
114
第 12章矢量数据空间操作:二元算子
128
第 13章空间索引
148
第 14章栅格数据读写:导入与导出
158
第 15章使用栅格数据
168
第 16章管理栅格数据
180
第 17章高级话题
190
第 18章运维
[0, 12, 22, 36, 50, 64, 78, 84, 88, 96, 102, 114, 128, 148, 158, 168, 180, 190, 202]
from pypdf import PdfWriter

pdf_idx = 1

from pathlib import Path
outws = Path(‘xx_post’)
if outws.exists():
pass
else:
outws.mkdir()

for qq, hh in zip(idx_arr[:-1], idx_arr[1:]):
outfile = outws / f’xx_{pdf_idx:02}.pdf’
print(outfile)

merger = PdfWriter()# add the first 3 pages of input1 document to output
merger.append(fileobj=pdfreader, pages=(qq, hh))# insert the first page of input2 into the output beginning after the second page
# merger.merge(position=2, fileobj=input2, pages=(0, 1))# append entire input3 document to the end of the output document
# merger.append(input3)# Write to an output PDF document
output = open(outfile, "wb")
merger.write(output)# Close File Descriptors
merger.close()
output.close()
pdf_idx =  pdf_idx + 1

xx_post/xx_01.pdf
xx_post/xx_02.pdf
xx_post/xx_03.pdf
xx_post/xx_04.pdf
xx_post/xx_05.pdf
xx_post/xx_06.pdf
xx_post/xx_07.pdf
xx_post/xx_08.pdf
xx_post/xx_09.pdf
xx_post/xx_10.pdf
xx_post/xx_11.pdf
xx_post/xx_12.pdf
xx_post/xx_13.pdf
xx_post/xx_14.pdf
xx_post/xx_15.pdf
xx_post/xx_16.pdf
xx_post/xx_17.pdf
xx_post/xx_18.pdf
4.2.3. 读取图片
PDF有扫描的图片,或者插入图片在内,首先验证文档是否加密。

pdffile = open(‘servers.pdf’,‘rb’)
pdfreader.is_encrypted
False
输出为False,即为没有加密过。

pg = pdfreader.pages[0]
pg.keys()
dict_keys([‘/Resources’, ‘/Contents’, ‘/Parent’, ‘/Type’, ‘/MediaBox’])
图片存储在 [‘/Resources’][‘/XObject’] 里,通过type查看发现 pg[‘/Resources’][‘/XObject’][‘/Im1’] 是一个EncodedStreamObject,通过 getData() 方法可以获取它的数据,直接以二进制模式写入文件即可保存。再使用前面使用的pillow库查看

pg.values()
dict_values([IndirectObject(322, 0, 140697627366992), [IndirectObject(321, 0, 140697627366992)], IndirectObject(1646, 0, 140697627366992), ‘/Page’, [0, 0, 595.27999999999997, 841.88999999999999]])
pg[‘/Resources’][‘/XObject’]


KeyError Traceback (most recent call last)

Cell In [9], line 1
----> 1 pg[‘/Resources’][‘/XObject’]

File /usr/lib/python3/dist-packages/pypdf/generic/_data_structures.py:269, in DictionaryObject.getitem(self, key)
268 def getitem(self, key: Any) -> PdfObject:
–> 269 return dict.getitem(self, key).get_object()

KeyError: ‘/XObject’

pg[‘/Resources’][‘/XObject’][‘/FXX1’]
im8 = pg[‘/Resources’][‘/XObject’][‘/FXX1’].get_data()
with open(‘im.png’, ‘wb’) as f:
f.write(im8)
from matplotlib import pyplot as plt
from PIL import Image
img=Image.open(‘./im.png’)
plt.imshow(img)
plt.show()


KeyError Traceback (most recent call last)

Cell In [11], line 1
----> 1 im8 = pg[‘/Resources’][‘/XObject’][‘/FXX1’].get_data()
2 with open(‘im.png’, ‘wb’) as f:
3 f.write(im8)

File /usr/lib/python3/dist-packages/pypdf/generic/_data_structures.py:269, in DictionaryObject.getitem(self, key)
268 def getitem(self, key: Any) -> PdfObject:
–> 269 return dict.getitem(self, key).get_object()

KeyError: ‘/XObject’

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/152466.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

原理Redis-ZipList

ZipList 1) ZipList的组成2) ZipList的连锁更新问题3) 总结 1) ZipList的组成 ZipList 是一种特殊的“双端链表” ,由一系列特殊编码的连续内存块组成。可以在任意一端进行压入/弹出操作, 并且该操作的时间复杂度为 O(1)。 ZipListEntry: ZipList 中的Entry并不像…

elementUI-表单-校验

配置校验 1、在el-form 标签上配置 <el-form ref"form" :model"form" label-width"120px" :rules"rules"><!-- 若干个的el-form-item标签 --> </el-form>其中 :model“form” 必须配置 表单数据对象 form 指的是…

怎么在echarts图上左右滑动切换数据区间

说在前面 不管前端还是后端&#xff0c;大家或多或少都了解使用过echarts图表吧&#xff0c;很多时候我们只是需要展示指定区间的数据&#xff0c;但有时我们希望在图表上能够轻松地切换数据的展示区间&#xff0c;以便更清晰地观察特定时间段或区域的变化。在本文中&#xff0…

【小爱学大数据】FlinkKafkaConsumer

今天小爱学习FlinkKafkaConsumer。 Apache Flink 是一个流处理和批处理的开源框架&#xff0c;它提供了数据流程序设计模型&#xff0c;以及运行环境和分布式执行引擎。FlinkKafkaConsumer 是 Flink 提供的一个 Kafka 消费者&#xff0c;用于从 Kafka 中消费数据。 下面是一个使…

kafka max.poll.records用法介绍

一、max.poll.records是什么 max.poll.records是Kafka consumer的一个配置参数&#xff0c;表示consumer一次从Kafka broker中拉取的最大消息数目。默认值为500条。 在Kafka中&#xff0c;一个consumer group可以有多个consumer实例&#xff0c;每个consumer实例负责消费一个…

贪吃蛇游戏制作

首先在ecilsp里面创建两个包&#xff0c;启动和图形界面 在创建一个文件夹用来放图片 1.绘制图形界面 package com.snaketuxing.view;import java.awt.Color; import java.awt.EventQueue; import java.awt.Font; import java.awt.Frame; import java.awt.Graphics; import …

Element UI 禁用数字输入框组件添加鼠标滚动事件

Element UI 禁用数字输入框组件添加鼠标滚动事件 <el-input type"number" mousewheel.native.prevent DOMMouseScroll.native.prevent :min"0" onkeyup"this.valuethis.value.match(/\d\.?\d{0,2}/);"v-model"form.threeYearDevelop…

实验三 循环结构程序设计(Python)

第1关:打印图形 zm=input("") #代码开始#代码结束def print_pattern(letter):if not letter.isalpha() or not letter.isupper():print("请输入大写字母")returnstart_char = Aend_char = letterfor i in range(ord(start_char), ord(end_char) + 1):spa…

win10蓝屏重启故障修复经验分享

1. 安全模式&#xff1a;尝试进入安全模式&#xff0c;按住Shift键并同时点击“重新启动”选项。然后选择“故障排除”>“高级选项”>“启动设置”>“重新启动”。在启动设置页面&#xff0c;按下F4或按4键选择进入安全模式&#xff0c;观察是否仍然出现蓝屏重启问题。…

cmake+OpenCV4.8.0+contrib4.8.0+cuda 12.2编译踩坑

cmakeOpenCV4.8.0contrib4.8.0cuda 12.2编译踩坑 准备工具 cmake &#xff08;去官网下载&#xff09;OpenCV 我下载的是官网发布最新的稳定版本对应的源码&#xff0c;官网目前是4.8.0&#xff0c;github下一个&#xff08;连不上的可以网上找找资源或者科学上网&#xff09…

【华为OD机试】分苹果【2023 B卷|100分】

【华为OD机试】-真题 !!点这里!! 【华为OD机试】真题考点分类 !!点这里 !! 题目描述 A、B两个人把苹果分为两堆,A希望按照他的计算规则等分苹果, 他的计算规则是按照二进制加法计算,并且不计算进位 12+5=9(1100 + 0101 = 9), B的计算规则是十进制加法,包括正常进位,…

听GPT 讲Rust源代码--src/bootstrap

图片来自 使用rust的image库进行图片压缩[1] File: rust/src/bootstrap/build.rs 在Rust源代码中&#xff0c;rust/src/bootstrap/build.rs这个文件是一个构建脚本。构建脚本是一个在编译Rust编译器本身时运行的程序&#xff0c;它用于初始化和配置Rust编译器的构建过程。build…

tcpdump使用方法

目录 安装 tcpdump 使用基本命令 示例 1. 捕获所有流量 2. 指定网络接口 3. 保存到文件 4. 显示包的详细信息 5. 过滤特定主机 6. 过滤特定端口 7. 组合过滤条件 更多选项和过滤表达式 tcpdump 是一个用于在命令行中进行网络抓包的工具&#xff0c;它允许你捕获和分…

基于SSM的焦作旅游协会管理系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

nginx学习(4)Nginx 负载均衡

负载均衡&#xff1a;是将负载分摊到不同的服务单元&#xff0c;既保证服务的可用性&#xff0c;又保证响应 足够快&#xff0c;给用户很好的体验。 在 linux 下有 Nginx、LVS、Haproxy 等等服务可以提供负载均衡服 务&#xff0c; 而且 Nginx 提供了几种分配方式(策略)&#…

rust打印闭包的插件实现

背景 “调试”编译器的某些行为时,可以通过编译器错误输出来判断 比如想知道一个类型是否实现了某个trait fn main() {use std::fmt::Debug;struct A;fn foo<T: Debug>(t: T) {}let a = A;foo(A); }提示:required by this bound in foo 意思就是:结构体A没有实现Deb…

ES6有何新特性?(下篇)

目录 函数参数的默认值设置 rest参数 扩展运算符 Symbol 迭代器 生成器 Promise Class 数值扩展 对象方法扩展 模块化 大家好呀&#xff01;今天这篇文章继续为大家介绍ES6的新特性&#xff0c;上上上篇文章介绍了一部分&#xff0c;这篇文章会将剩下的部分新增的特…

ES索引数据清理脚本示例

说明&#xff1a;我得索引是按月份创建的&#xff0c;索引名后面都有yyyy.MM 需求&#xff1a;删除三个月以前的索引&#xff0c;清理收集的应用日志数据&#xff0c;释放磁盘空间 #!/bin/bash# 定义 Elasticsearch 节点的地址 ELASTICSEARCH_HOST"192.168.53.100" …

虚拟化逻辑架构: 创建KVM中的VM与实现VNC远程登录

目录 一、实验 1.安装KVM环境管理工具并创建VM&#xff08;虚拟机&#xff09; 2.Windows使用VNC Viewer连接KVM中的VM&#xff08;虚拟机&#xff09; 二、问题 1.如何下载安装VNC Viewer 一、实验 1.安装KVM环境管理工具并创建VM&#xff08;虚拟机&#xff09; (1) 采…

德迅云安全和您聊聊关于DDOS高防ip的一些方面

德迅DDoS防护服务是以省骨干网的DDoS防护网络为基础&#xff0c;结合德迅自研的DDoS攻击检测和智能防护体系&#xff0c;向您提供可管理的DDoS防护服务&#xff0c;自动快速的缓解网络攻击对业务造成的延迟增加&#xff0c;访问受限&#xff0c;业务中断等影响&#xff0c;从而…