【问题标题】:Converting PDF to text: "Text extraction is not allowed"将 PDF 转换为文本:“不允许提取文本”
【发布时间】:2019-01-02 16:31:23
【问题描述】:

我正在尝试将 PDF 转换为 Python 中的文本。但它给了我一个错误:

PDFTextExtractionNotAllowed:不允许提取文本:<_io.bufferedreader name="C:\Users\Downloads\Facts_for_2017.pdf">

我使用的代码是:

import sys
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter
from pdfminer.layout import LAParams
import io    


def pdfparser(data):
    fp = open(data, 'rb')      
    rsrcmgr = PDFResourceManager()
    retstr = io.StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    interpreter = PDFPageInterpreter(rsrcmgr, device)

    for page in PDFPage.get_pages(fp):
        interpreter.process_page(page)
        data = retstr.getvalue()

    return data


if __name__ == '__main__':
    text = pdfparser(Input_path)

谁能帮帮我?

文件路径是:

https://drive.google.com/file/d/1RyR-J-EwMywL6BqsYbl4Ocm96VzCYrM7/view?usp=sharing

【问题讨论】:

标签: python python-3.x pdfminer


【解决方案1】:

问题在于PDFPage.get_pages() 按照惯例检查文本是否可提取。您必须将标志设置为check_extractable=False 才能使其工作。此外,如果您尝试转换为 txt 的 PDF 受密码保护,您也可以在此处进行更改。很遗憾,PDFPagedocumentation 不是很清楚。

password = ""
for page in PDFPage.get_pages(fp, check_extractable=False, password=password):
    interpreter.process_page(page)
data = retstr.getvalue()

您的整个代码如下所示:

import io

from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfinterp import PDFPageInterpreter, PDFResourceManager
from pdfminer.pdfpage import PDFPage

def pdfparser(data):
    rsrcmgr = PDFResourceManager()
    retstr = io.StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)

    interpreter = PDFPageInterpreter(rsrcmgr, device)
    password = ""
    maxpages = 0
    caching = True
    pagenos = set()

    with open(data, 'rb') as fp:
        for page in PDFPage.get_pages(fp,
                                      pagenos, 
                                      maxpages=maxpages,
                                      password=password,
                                      caching=caching,
                                      check_extractable=False):
            interpreter.process_page(page)

    # As pointed out in another answer, this goes outside the loop
    text = retstr.getvalue()

    device.close()
    retstr.close()
    return text

注意:Python 的 with open ...: 模式实现对于正确处理文件对象很有用。

【讨论】:

    【解决方案2】:

    您收到错误是因为,data = retstr.getvalue() 行中的缩进错误,它应该在 for 循环之外。

    但是,在修复之后,我遇到了一些其他问题,所以我提供了下面的完整代码:

    import sys
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
    from pdfminer.pdfpage import PDFPage
    from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter
    from pdfminer.layout import LAParams
    import io    
    
    
    def pdfparser(data):
        fp = open(data, 'rb')      
        rsrcmgr = PDFResourceManager()
        # retstr = io.StringIO() #This will cause -- `TypeError: unicode argument expected, got 'str'`
        retstr = io.BytesIO()
        codec = 'utf-8'
        laparams = LAParams()
        device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
        interpreter = PDFPageInterpreter(rsrcmgr, device)
    
        for page in PDFPage.get_pages(fp):
            interpreter.process_page(page)
    
        data = retstr.getvalue() #Indentation was worng here
        fp.close()
        #print(data)
        return data
    
    
    if __name__ == '__main__':
        #PDF file you provied is encrypted with blank password, we need to decrypt it
        path = sys.argv[1]
        from subprocess import call
        import os
        pdf_filename = os.path.basename(path)
        file_name, extension = os.path.splitext(pdf_filename)
        pdf_filename_decr = str(file_name) + "_decr" + extension
        call('qpdf --password=%s --decrypt %s %s' %('', path, pdf_filename_decr), shell=True)
    
        text = pdfparser(pdf_filename_decr)
    

    【讨论】:

    • 这个缩进是由编辑过代码的人引入的。之前没有任何缩进!
    • 感谢您的回复。我想问一下 pdf_filename_decr 会保存在哪里?当我运行这个程序时,它给出了 FileNotFound 错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-25
    • 2015-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多