前言

图片

上次用的方法是把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, pages

    4. 根据「待提取的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 chp11

    b. 也可以在文件里设置好变量

filename = "chp01.pdf"  # 改相应的文件名

        然后直接

python3 latex_pdf_filter.py
0
0