如何在Python中解锁“安全”(读保护)PDF?

时间:2015-01-28 13:02:09

标签: python pdf pdfminer pdf-scraping

在Python中,我使用pdfminer从pdf中读取文本,并在此消息下面显示代码。我现在收到一条错误消息:

File "/usr/local/lib/python2.7/dist-packages/pdfminer/pdfpage.py", line 124, in get_pages
    raise PDFTextExtractionNotAllowed('Text extraction is not allowed: %r' % fp)
PDFTextExtractionNotAllowed: Text extraction is not allowed: <cStringIO.StringO object at 0x7f79137a1
ab0>

当我用Acrobat Pro打开这个pdf时,它证明它是安全的(或“读保护”)。然而,从this link开始,我读到有很多服务可以轻松禁用这种读取保护(例如pdfunlock.com。当深入了解pdfminer的源代码时,我发现上面的错误是在these lines

if check_extractable and not doc.is_extractable:
    raise PDFTextExtractionNotAllowed('Text extraction is not allowed: %r' % fp)

由于有许多服务可以在一秒钟内禁用这种读保护,我认为这很容易做到。似乎.is_extractabledoc的简单属性,但我认为这不如将.is_extractable更改为True那么简单。

有人知道如何使用Python禁用pdf上的读取保护吗?欢迎所有提示!

=============================================== =

您将在下面找到我目前从非读保护文件中提取文本的代码。

def getTextFromPDF(rawFile):
    resourceManager = PDFResourceManager(caching=True)
    outfp = StringIO()
    device = TextConverter(resourceManager, outfp, codec='utf-8', laparams=LAParams(), imagewriter=None)
    interpreter = PDFPageInterpreter(resourceManager, device)

    fileData = StringIO()
    fileData.write(rawFile)
    for page in PDFPage.get_pages(fileData, set(), maxpages=0, caching=True, check_extractable=True):
        interpreter.process_page(page)
    fileData.close()
    device.close()

    result = outfp.getvalue()

    outfp.close()
    return result

7 个答案:

答案 0 :(得分:15)

据我所知,在大多数情况下,使用密码作为加密密钥,PDF的全部内容实际上是加密的,因此只需将.is_extractable设置为True即可帮助你。

根据这个帖子:

Does a library exist to remove passwords from PDFs programmatically?

我建议使用命令行工具删除读保护,例如qpdf(可以轻松安装,例如在Ubuntu上使用apt-get install qpdf,如果你还没有):

qpdf --password=PASSWORD --decrypt SECURED.pdf UNSECURED.pdf

然后使用pdfminer打开解锁文件并执行操作。

对于纯Python解决方案,您可以尝试使用PyPDF2及其.decrypt()方法,但它不适用于所有类型的加密,所以真的,你最好只使用qpdf - 请参阅:

https://github.com/mstamy2/PyPDF2/issues/53

答案 1 :(得分:5)

我在尝试使qpdf在程序中运行时遇到一些问题。我发现了一个有用的库pikepdf,它基于qpdf,并自动将pdf转换为可提取的。

使用此代码非常简单:

import pikepdf

pdf = pikepdf.open('unextractable.pdf')
pdf.save('extractable.pdf')

答案 2 :(得分:2)

在我的情况下,没有密码,只是设置check_extractable=False绕过有问题的文件的PDFTextExtractionNotAllowed例外(在其他查看器中打开正常)。

答案 3 :(得分:1)

我使用下面的代码并且能够覆盖。

pdf = pikepdf.open('filepath', allow_overwriting_input=True)
pdf.save('filepath')

答案 4 :(得分:0)

'check_extractable = True'参数是设计使然。 某些PDF明确禁止提取文本,PDFMiner遵循该指令。您可以覆盖它(给出check_extractable = False),但后果自负。

答案 5 :(得分:0)

我也同样遇到了解析安全pdf的问题,但是使用pikepdf库已经解决了。我在jupyter notebbok和Windows os上尝试了该库,但出现了错误,但在Ubuntu上能正常运行

答案 6 :(得分:0)

如果要解锁文件夹中的所有pdf文件而不重命名它们,则可以使用以下代码:

import glob, os, pikepdf

p = os.getcwd()
for file in glob.glob('*.pdf'):
   file_path = os.path.join(p, file).replace('\\','/')
   init_pdf = pikepdf.open(file_path)
   new_pdf = pikepdf.new()
   new_pdf.pages.extend(init_pdf.pages)
   new_pdf.save(str(file))

pikepdf库中,无法通过使用相同名称保存来覆盖现有文件。相反,您希望将页面复制到新创建的空pdf文件中,然后保存。