原标题:超级实用干货|九大技巧,带你用Python玩转PDF

尽管PDF最开始是由Adobe发明的,但它现在已经成为国际标准组织ISO维护的公开标准了。大家可以在Python中通过PyPDF2包来处理已存在的PDF。PyPDF2是一个纯Python的包,通过它可以进行多种不同类型的PDF操作。通过阅读本文,您将了解以下技能:

提取PDF信息

旋转PDF页面

合并PDF

拆分PDF

添加水印

加密PDF

目录

·PyPdf、PyPDF2、PyPDF4的发展史

·PDF工具包:pdfrw

·安装 PyPDF2

·提取PDF信息

·旋转PDF页面

·合并PDF

·拆分PDF

·添加水印

·加密PDF

·总结

01

PyPdf、PyPDF2、PyPDF4的发展史

最初的pyPdf包是在2005年发行的。最后一个官方pyPdf是在2010年发行的。大约一年后,一家名为Phasit的公司赞助了pyPdf的一个分支PyPDF2。这个包的代码可以与最初的版本兼容,并且在好几年内都运行得相当好,直到2016年发行最后一版。

在PyPDF3发布了几个版本后,项目被重命名为PyPDF4。虽然这些项目版本几乎做同样的事,但pyPdf和PyPDF2+之间最大的不同在于后来的版本支持Python3。虽然Python3也有一个原始pyPdf分支,但并没有维持多少年。

尽管PyPDF2最近不再使用,新的PyPDF4也无法完全向后兼容PyPDF2。尽管本文的大多数例子使用PyPDF4都运行得非常顺利,但其中有一些不行,这正是本文没有过多强调PyPDF4的原因。当然,您也可以导入PyPDF4来替换PyPDF2,观察它是如何实现的。

02

PDF工具包:pdfrw

Patrick Maupin 发明了pdfrw包,可以完成很多PyPDF2的工作。您可以使用pdfrw处理本文中用PyPDF2处理的同类型任务,加密任务除外。

pdfrw最大的不同在于整合了ReportLab包,因此您可以使用已存在的PDF,通过ReportLab将这些已存在的PDF的部分或全部创建成新的文档。

03

安装PyPDF2

如果您刚好使用Anaconda,而不是纯Python,可以用pip或者conda安装PyPDF2,以下用pip安装PyPDF2。

pipinstall pypdf2

PyPDF2的安装不需要依赖任何包,所以安装很快,并且下载包的速度和安装的速度差不多。

04

提取PDF信息

您可以使用PyPDF2从PDF中提取元数据和一些文本。当您在已存在的PDF文件中执行某些类型的自动化时,这会比较有用。

可以提取的数据类型如下:

·作者

·创建者

·生成器

·主题

·标题

·页数

您需要找到一个PDF来运行这个例子,电脑上的任意PDF皆可。为了简便,我去Leanpub选取了我一本书中的一个样本。您可以下载这个样本—reportlab-sample.pdf.

以下代码处理PDF,您可以了解到这些属性:

# extract_doc_info.py

fromPyPDF2 importPdfFileReader

defextract_information(pdf_path):

withopen(pdf_path, 'rb') asf:

pdf = PdfFileReader(f)

information = pdf.getDocumentInfo()

number_of_pages = pdf.getNumPages()

txt = f"""

Information about {pdf_path}:

Author: {information.author}

Creator: {information.creator}

Producer: {information.producer}

Subject: {information.subject}

Title: {information.title}

Number of pages: {number_of_pages}

"""

print(txt)

returninformation

if__name__ == '__main__':

path = 'reportlab-sample.pdf'

extract_information(path)

从PyPDF2包中导入PdfFileReader。PdfFileReader是一个类,包含与PDF文件交互的几个方法。在此例子中,调用.getDocumentInfo(),返回DocumentInformation的一个实例,包含了您感兴趣的大多数信息。您也可以调用对象的.getNumPages(),返回文件的页数。

可以用Information变量的几个属性来获取文档中的其余元数据。可以打印出信息和返回信息以备未来之需。

尽管PyPDF2的.extractText()可用在页数对象上(此例子未展示),但并不好用。因为有些PDF会返回文本内容,有些则会返回空字符。当您希望从一篇PDFF中提取文档,您需要检查PDFMiner。PDFMiner是专门为从PDF中提取文档的功能设计的,更为稳定。

【注】最后一段代码使用Python3最新的字符串格式。如果您想学习更多,可以查阅Python 3’s f-Strings: An Improved String Formatting Syntax (Guide).

05

旋转PDF页面

有时候,您会收到一些横向模式而不是纵向模式的PDF,或者这些文档是上下颠倒的。如下图:

这种情况经常出现在人们把文件扫描成PDF或者邮件。您可以打印文件,了解文章版本,或者使用Python旋转有问题的页面。在此例中,您可以去往Real Python article 打印PDF来学习PyPDF2。

以下是用PyPDF2旋转文章页面的代码:

# rotate_pages.py

fromPyPDF2 importPdfFileReader, PdfFileWriter

defrotate_pages(pdf_path):

pdf_writer = PdfFileWriter()

pdf_reader = PdfFileReader(path)

# Rotate page 90 degrees to the right

page_1 = pdf_reader.getPage( 0).rotateClockwise( 90)

pdf_writer.addPage(page_1)

# Rotate page 90 degrees to the left

page_2 = pdf_reader.getPage( 1).rotateCounterClockwise( 90)

pdf_writer.addPage(page_2)

# Add a page in normal orientation

pdf_writer.addPage(pdf_reader.getPage( 2))

withopen( 'rotate_pages.pdf', 'wb') asfh:

pdf_writer.write(fh)

if__name__ == '__main__':

path = 'Jupyter_Notebook_An_Introduction.pdf'

rotate_pages(path)

"""

print(txt)

return information

if __name__ == '__main__':

path = 'reportlab-sample.pdf'

extract_information(path)

在此例中,您需要导入PdfFileWriter和PdfFileReader,因为您需要输出新的PDF。rotate_pages()输入您想要修正的PDF路径。在这个功能中,您需要创建一个写对象pdf_writer,一个读对象pdf_reader。

然后,您可以使用.getPage()获取想要的页面。您可以抓取页面0,即首页。然后您可以调用页面对象的.rotateClockwise()方法,输入90度。同样的,对于页面2,您可以调用.rotateCounterClockwise()并输入90度。

每次调用旋转方法后,调用.addPage()来添加页面的旋转版本到写对象。添加到写对象的最后一页是没有任何旋转的页面3。

最后,用.write()写入新的PDF,其用file-like object作为参数。新的PDF包含3页,前两页以相反方向旋转成横向,第三页正常。

【注】PyPDF2包只允许您以90度的增量旋转页面,如90、180、270……,否则会收到Asserti报错。

06

合并PDF

很多情况下需要将两个或多个PDF合并成一个PDF。比如,有一个标准封面需要加到多种类型的报告中。您可以使用Python帮您处理。

在此例中,您可以打开一个PDF,输出一个页面作为独立的PDF,重复输出获得不同页面,这样就有两个输入作为本例的目的。以下是合并的代码:

# pdf_merging.py

fromPyPDF2 importPdfFileReader, PdfFileWriter

defmerge_pdfs(paths, output):

pdf_writer = PdfFileWriter()

forpath inpaths:

pdf_reader = PdfFileReader(path)

forpage inrange(pdf_reader.getNumPages()):

# Add each page to the writer object

pdf_writer.addPage(pdf_reader.getPage(page))

# Write out the merged PDF

withopen(output, 'wb') asout:

pdf_writer.write(out)

if__name__ == '__main__':

paths = [ 'document1.pdf', 'document2.pdf']

merge_pdfs(paths, output= 'merged.pdf')

若想合并一系列PDF,可以调用merge_pdfs(),并且需要知道保存结果的路径。因此这个函数的输入参数是这些PDF的路径以及结果保存的路径。

然后遍历原PDF的路径,并为每个路径创建一个PDF读对象。接着,您需要遍历该路径对应的PDF所有页面,通过.addPage()添加到页面本身。完成所有PDF所有页面的处理后,即可以进行写操作,输出PDF。

需要注意的是,如果您不想合并每个PDF的所有页面,需要添加一系列要添加的页面来强化这个脚本。若您愿意挑战,也可以使用Python的argparse模块为这功能创建命令行界面。

07

拆分PDF

有时候需要将一个PDF拆分成多个PDF,尤其当PDF包含很多扫描的内容,但是也有众多其它原因需要去拆分PDF。以下是使用PyPDF2将一个PDF拆分成多个。

# pdf_splitting.py

fromPyPDF2 importPdfFileReader, PdfFileWriter

defsplit(path, name_of_split):

pdf = PdfFileReader(path)

forpage inrange(pdf.getNumPages()):

pdf_writer = PdfFileWriter()

pdf_writer.addPage(pdf.getPage(page))

output = f'{name_of_split}{page}.pdf'

withopen(output, 'wb') asoutput_pdf:

pdf_writer.write(output_pdf)

if__name__ == '__main__':

path = 'Jupyter_Notebook_An_Introduction.pdf'

split(path, 'jupyter_page')

在此例中,首先创建PDF读对象,并遍历页面。对每个页面,创建新的PDF写实例,并添加新的页面。然后将页面写入独立命名的文件。当脚本结束运行,得到原始PDF的每个页面拆分成独立PDF。

08

添加水印

水印可以识别印刷和数字文件的图片和图像模式。有些水印只能在特殊光照条件下才能看见。水印非常重要,可以保护知识产权,比如图像或者PDF。水印的另一术语是叠加。

可以通过Python和PyPDF2为文件添加水印。您的PDF必须只包含水印图或者文本。以下是添加水印代码:

# pdf_watermarker.py

fromPyPDF2 importPdfFileWriter, PdfFileReader

defcreate_watermark(input_pdf, output, watermark):

watermark_obj = PdfFileReader(watermark)

watermark_page = watermark_obj.getPage( 0)

pdf_reader = PdfFileReader(input_pdf)

pdf_writer = PdfFileWriter()

# Watermark all the pages

forpage inrange(pdf_reader.getNumPages()):

page = pdf_reader.getPage(page)

page.mergePage(watermark_page)

pdf_writer.addPage(page)

withopen(output, 'wb') asout:

pdf_writer.write(out)

if__name__ == '__main__':

create_watermark(

input_pdf= 'Jupyter_Notebook_An_Introduction.pdf',

output= 'watermarked_notebook.pdf',

watermark= 'watermark.pdf')

create_watermark()接收三个参数:

①input_pdf:需要加水印的PDF路径

②output:水印版本PDF的保存路径

③watermark:含有水印图像或文本的PDF

代码中,打开水印PDF,从文档的第一页抓取信息,因为第一页即保存了水印内容。然后用input_pdf创建PDF读对象并创建通用的pdf_writer对象来写入加了水印的PDF。

下一步是遍历input_pdf的所有页面,魔法开始了。调用.mergePage()并传入watermark_page。这一步是将水印页面叠加到现有页面中,然后将新的叠加页面添加到pdf_writer对象中。最后,把新的加了水印的PDF写入到磁盘中,完成。

09

加密PDF

PyPDF2目前只支持对已有PDF添加用户密码和所有者密码。在PDF中,所有者密码基本上拥有对该PDF的管理员权限,允许对文档设置权限。另一方面, 用户密码仅允许打开文件。

正如所说的,PyPDF2事实上并不能对文档设置任何权限,即使可以设置所有者密码。无论如何,以下是添加密码、本质上加密PDF的代码:

# pdf_encrypt.py

fromPyPDF2 importPdfFileWriter, PdfFileReader

defadd_encryption(input_pdf, output_pdf, password):

pdf_writer = PdfFileWriter()

pdf_reader = PdfFileReader(input_pdf)

forpage inrange(pdf_reader.getNumPages()):

pdf_writer.addPage(pdf_reader.getPage(page))

pdf_writer.encrypt(user_pwd=password, owner_pwd= None,

use_128bit= True)

withopen(output_pdf, 'wb') asfh:

pdf_writer.write(fh)

if__name__ == '__main__':

add_encryption(input_pdf= 'reportlab-sample.pdf',

output_pdf= 'reportlab-encrypted.pdf',

password= 'twofish')

add_encryption()需要传入输入和输出PDF的路径以及添加到PDF的密码。打开PDF读和写对象,遍历PDF所有页面并添加到写对象。最后调用.encrypt(),参数为用户密码、所有者密码以及是否128位加密。默认128位加密,若设置False, 则为40位加密。

【注】根据pdflib.com,PDF加密技术要么采用RC4,要么采用AES(Advanced Encryption Standard)。因为加密了PDF并不意味着百分百安全,也有一些工具能从PDF中删除密码。若想了解更多,卡内基梅隆大学在这方面有一个有趣的论文【1】。

10

总结

PyPDF2包相当有用,通常情况下也比较快。您可以使用PyPDF2自动化大量的工作,利用其能力帮您更好地工作。

在此教程中,包含了以下内容:

·从PDF提取元数据

·旋转页面

·合并和拆分PDF

·添加水印

·加密PDF

基于以上基本功能,也可以拓展其它功能,如删除页面。代码如下:

# pdf_delete.py

from PyPDF2 import PdfFileWriter, PdfFileReader

def delete( path, name_of_delete, delete_page):

pdf_reader = PdfFileReader( path)

pdf_writer = PdfFileWriter()

forpage inrange( 0, delete_page):

pdf_writer.addPage(pdf_reader.getPage(page))

forpage inrange(delete_page+ 1, pdf_reader.getNumPages()):

pdf_writer.addPage(pdf_reader.getPage(page))

output= f '{name_of_delete}.pdf'

withopen(output_pdf, 'wb') asfh:

pdf_writer.write(fh)

if__name__ == '__main__':

path= 'merged.pdf'

delete( path, name_of_delete= 'new.pdf', delete_page= 2)

在此删除例子中,输入原PDF路径和删除后需要保存的路径以及删除页面(本例为第3页),然后通过读对象向写对象添加除了第三页之外的所有页面,然后写入磁盘保存。若删除多页,只要在循环添加页面时省去那些页面即可。大家也可以考虑更多的功能。

关注更新的PyPDF4,不久后它将取代PyPDF2。您也可以尝试pdfrw,实现PyPDF2能做的同样的任务。返回搜狐,查看更多

责任编辑:

python实用大全pdf_超级实用干货|九大技巧,带你用Python玩转PDF相关推荐

  1. 九大神招,让Python里数据分析神器Jupyter,完美升华

    九大神招,让Python里数据分析神器Jupyter,完美升华 Notebook作为一款经典的交互式编辑器,在视图数据等实时展示方面有其特有的优势,但是相比pycharm.sublime等编辑工具,J ...

  2. 计算机高手必会的东西,【技巧百科】1分钟学会电脑高手必备的九大技巧,最后一条厉害了!...

    原标题:[技巧百科]1分钟学会电脑高手必备的九大技巧,最后一条厉害了! 今天来给大家分享八个电脑使用技巧,帮你提升效率,顺便可以在同事.朋友面前装装样子.最关键的是,这点小事,以后就可以自己来操作了, ...

  3. python查看数据大小_科多大数据带你看Python可以列为最值得学习的编程语言

    原标题:科多大数据带你看Python可以列为最值得学习的编程语言 不知道从什么时候开始,这句话开始流行.不过也从侧面反映出 Python 语言的特点:简单.高效. 从近期代表技术趋势的业界报告以及编程 ...

  4. 提高订单成交率的九大技巧,你还不知道吗?

    在做外贸的过程中,外贸业务员往往给客户发了订单后得不到回应,如何提高订单的成交率成了困扰外贸业务员的一大难题.下面介绍九大技巧仅供参考. 要提高订单的成交率,外贸业务员可采用以下九大技巧: 技巧一,让 ...

  5. 总裁演说思维商务谈判中的九大技巧

    总裁演说思维商务谈判中的九大技巧 说起谈判,总让人感到一股双方对决的杀戮之气,令人不寒而栗.嗯,其实你想太多了,谈判真正的本质,就是一种解决问题的思考模式,所以谈判是说服,更是协调冲突.而谈不定,工作 ...

  6. pr玩转特效的九大技巧

    pr玩转特效的九大技巧 直接花字法 表情包配图法 矢量素材法 GF动图法 特效素材法 背景音乐法 头部放大法 换衣法 电影片段法 1. 直接花字法 .加入图标做修饰 一般可以通过转场和关键帧做出动画效 ...

  7. 让你的网站关键词排名排到首页的九大技巧

    这九大技巧是最基本最简单的要求,而让你的网站关键词排名排到首页的九大技巧不管怎么样如果真的能运用到实战中,对于网站排名是有非常大帮助的. 第一:服务器因素 1.服务器的地区分布影响排名 如果相同的英文 ...

  8. 网站优化的九大技巧,助力您的SEO策略

    网站已经成为现代企业宣传和销售的重要平台.如何让自己的网站在搜索引擎中获得更高的排名,是很多企业关注的问题.网站优化(SEO)是一种提高网站在搜索引擎中排名的技术,本文将介绍9个优化技巧,助力您的SE ...

  9. python模块大全_哎呀,不错哦!3步带你用Python打造一款智能语音聊天小软件

    最近小编与中科院的同学吃饭的时候,偶然讲起来他最近的一个项目就是利用语音识别的技术和聊天机器人来实现人机交互,简而言之就是我们说话,程序识别出来我们讲的是什么,然后通过聊天机器人跟我们实现交流.我感到 ...

最新文章

  1. Kubernetes是什么
  2. 使用Hyperledger Ursa简化区块链安全性
  3. [导入] 堆和栈的区别
  4. SAP WebClient UI删除搜索条件的后台处理,以及max hit的处理逻辑
  5. 进程前台运行后台运行的相关命令
  6. poj 3071 Football
  7. jQuery LigerUI 初次发布一睹为快(提供Demo下载)
  8. QTP 11.05下载并完成+皴
  9. 全国大学生数学建模竞赛首战一等奖经验分享
  10. 计算机组成原理实验:基本运算器实验
  11. 从你的全世界路过—一群程序员的稻城亚丁游记
  12. 元宵节代码,元宵节快乐代码,元宵节祝福代码
  13. 取得平均薪水最高的部门的部门名称
  14. 操作系统----进程间通信的方式
  15. 京东校园招聘2019.04.13 第一题 01序列拉齐
  16. 102道java算法
  17. Python将两个EXCEL去除(或保留)重复数据
  18. 初学者如何快速开发大数据分析平台
  19. 沉淀自己(此文无价)
  20. 菜鸟成长记----做一个简易的搜索引擎

热门文章

  1. 实战:大数据营销 微信朋友圈广告
  2. 通常IT创业可以有7种盈利方式
  3. win10安装openssl
  4. Bitmap这个“内存刺客”你要小心~
  5. 家园系统服务器,1月13日服务器更新 调整家园系统帮盟系统
  6. ArrayList, LinkedList, Vector - dudu:史上最详解
  7. MSP430 F5529 硬件SPI OLED 单片机 0.96英寸7针OLED SPI 6针OLED
  8. 【MSP430】MSP430F5529关于ADC12模数转换介绍
  9. 物联网-物联前端安全加密技术简介
  10. Android uart driver