Преобразование PDF в текст: «Извлечение текста не допускается» - PullRequest
0 голосов
/ 02 января 2019

Я пытаюсь конвертировать 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

Ответы [ 2 ]

0 голосов
/ 02 апреля 2019

Проблема в том, что PDFPage.get_pages() проверяет, является ли текст извлекаемым по соглашению. Вы должны установить флаг check_extractable=False, чтобы он работал. Кроме того, если PDF-файл, который вы пытаетесь преобразовать в txt, защищен паролем, вы также можете изменить его там. К сожалению, документация PDFPage не совсем ясна.

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

ПРИМЕЧАНИЕ. Реализация шаблона with open ...: в Python полезна для правильной обработки файловых объектов.

0 голосов
/ 02 января 2019

Вы получаете ошибку, потому что отступ в строке с 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)
...