前言
上次用的方法是把pdf转成图片二维数组来分析重复部分,其实这种思路用起来还是心里打鼓的,不敢确定能不能百分百判断「重复页」和「新起一页」。
这篇文章要讲的方法更有效,我可以绝对放心,但是也有应用场景的限制:
- 每一页pdf页面上写有作为PPT显示时候的页码。即不是pdf阅读器显示的页码,同一个PPT页码可以对应多页pdf。比如上面那张图。
- 显示的PPT页码位置固定
- 页码文本可选
动手
限制说完,代码思路也就出来了。(代码中PyPDF2版本为2.x)
1. 对每一页进行文本提取,得到对应每一页的字符串。
2. 对字符串做正则匹配或固定位置切片提取,得到PPT页码文本。
3. 相同页码文本是同一页,以相同PPT页码文本的最后一页pdf页码为待会要提取的页,存储为一个「待提取的pdf页码」数组。
def getPdfIndex(filename):
pdf = PdfFileReader(open(filename, "rb"))
indexs = []
pages = []
now = ""
for i in range(0, pdf.getNumPages()):
pageObj = pdf.getPage(i)
content = pageObj.extractText()
index = content.split("\n")[-2]
if now != index:
pages.append(i-1)
now = index
indexs.append(index)
pageCount = pdf.getNumPages()
pages.remove(-1)
pages.append(pageCount-1)
return indexs, pages4. 根据「待提取的pdf页码」数组提取页面,导出新pdf。
def splitPdf(filename, pages):
assert filename[-4:] == '.pdf'
output = PdfFileWriter()
pdf_file = PdfFileReader(open(filename, "rb"))
for i in pages:
output.addPage(pdf_file.getPage(i))
filename = filename.replace('\\', '/').split('/')[-1]
outputStream = open("[Splited] "+filename, "wb")
output.write(outputStream)多说几句
最后补一句,就算页码不能直接文本提取也没关系,OCR 就好了。
不过,要是没有PPT页码,那就只能用上回推送说的代码了,上次的代码应该是很通用的了。
怎么用
仓库地址还是这个:https://github.com/Benature/pdf-helper
这次说的代码在 pdf_filter/latex_pdf_filter.py 文件内。
使用方法有两种,比如想处理 chp11.pdf 文件
a. 可以直接命令行
python3 latex_pdf_filter.py chp11b. 也可以在文件里设置好变量
filename = "chp01.pdf" # 改相应的文件名然后直接
python3 latex_pdf_filter.py