Модуль Python для преобразования PDF в текст

Есть ли какой-либо модуль Python для преобразования файлов PDF в текст? Я попробовал один фрагмент кода, найденный в Activestate, который использует pypdf, но сгенерированный текст не имеет пробелов между ними и бесполезен.

Искал подобное решение. Мне просто нужно прочитать текст из pdf файла. Мне не нужны изображения. pdfminer - хороший выбор, но я не нашел простого примера, как извлечь текст. Наконец я получил этот SO-ответ (stackoverflow.com/questions/5725278/…) и теперь использую его.

Nayan 02.03.2016 11:43

Поскольку вопрос был закрыт, я разместил его на Stack Exchange, посвященном рекомендациям по программному обеспечению на случай, если кто-то захочет написать новый ответ: Модуль Python для преобразования PDF в текст

Franck Dernoncourt 28.04.2017 05:47

Единственное решение, которое сработало для меня для содержимого UTF-8: Apache Tika

Shoham 04.03.2018 23:41

Я хотел бы обновить список доступных опций для преобразования PDF в текст в Python, GroupDocs.Conversion Cloud SDK для Python точно преобразует PDF в текст.

Tilal Ahmad 25.10.2019 17:02
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
400
4
380 007
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

Ответ принят как подходящий

Попробуйте PDFMiner. Он может извлекать текст из файлов PDF в формате HTML, SGML или «PDF с тегами».

Формат PDF с тегами кажется самым чистым, и при удалении тегов XML остается только пустой текст.

Версия Python 3 доступна по ссылке:

Я только что добавил ответ, описывающий, как использовать pdfminer в качестве библиотеки.

codeape 24.11.2008 17:21

нет поддержки Python 3 :(

Karl Adler 19.12.2014 19:13

Ответ, который я дал в эта ветка, может быть полезен для людей, которые смотрят этот ответ и задаются вопросом, как использовать библиотеку. Я привожу пример того, как использовать библиотеку PDFMiner для извлечения текста из PDF. Поскольку документация немного скудна, я подумал, что это может помочь некоторым людям.

DuckPuncher 13.02.2015 19:56

Не могли бы вы помочь мне понять, как конвертировать pdf в формат pdf с тегами?

user199354 09.09.2015 08:55

что касается python 3, есть вилка pypi.python.org/pypi/pdfminer.six на основе шести

Denis Cornehl 04.12.2015 13:10

пример кода в stackoverflow.com/a/26495057/125617

Renaud 07.01.2016 00:38

pdfminder поставляется с утилитой командной строки, которую удобно использовать с PDF-файлами, которые представляют собой настоящий текст: unixuser.org/~euske/python/pdfminer/index.html#pdf2txt.

ccpizza 10.03.2017 21:46

К сожалению, pdfminer не очень быстр, особенно если вы собираетесь использовать его для длинных PDF-документов, содержащих более 100 страниц.

Pedram 11.07.2017 08:46

Вот рабочий пример с pdfminer.six от мая 2020 года. from pdfminer.high_level import extract_text, затем text = extract_text('report.pdf')stackoverflow.com/a/61857301/7483211

Cornelius Roemer 17.05.2020 22:16

PDFminer дал мне, возможно, одну строчку [страница 1 из 7 ...] на каждой странице файла pdf, который я пробовал с ним.

Лучший ответ, который у меня есть, - это pdftoipe или код на C++, основанный на Xpdf.

см. мой вопрос, чтобы узнать, как выглядит вывод pdftoipe.

PDFtotext Программа с открытым исходным кодом (часть Xpdf), которую вы можете вызывать из python (не то, что вы просили, но может быть полезно). Использую без проблем. Я думаю, что Google использует его на рабочем столе Google.

Это, по-видимому, самый полезный из перечисленных здесь инструментов с опцией -layout, позволяющей сохранять текст в том же положении, что и в PDF. Если бы я только мог понять, как передать в него содержимое PDF-файла.

Matthew Schinckel 31.05.2012 10:00

После тестирования нескольких решений это кажется самым простым и надежным вариантом. Python может легко обернуть его, используя временный файл, чтобы указать, куда записывать вывод.

Cerin 29.10.2012 19:14
Cerin, use '-' as a file name to redirect output to stdout. This way you can use simple subprocess.check_output and this call would feel like an internal function.
Ctrl-C 15.07.2014 12:55

Просто чтобы усилить всех, кто его использует. . . pdftotext, похоже, работает очень хорошо, но ему нужен второй аргумент - дефис, если вы хотите увидеть результаты в stdout.

Gordon Linoff 02.06.2015 18:53

Это рекурсивно преобразует все файлы PDF, начиная с текущей папки: find . -iname "*.pdf" -exec pdftotext -enc UTF-8 -eol unix -raw {} \; По умолчанию сгенерированные файлы принимают исходное имя с расширением .txt.

ccpizza 10.03.2017 22:03

import subprocesssubprocess.call(("pdftotext ... ).split())

vstepaniuk 02.08.2019 16:38

вместо выполнения вызова командной строки в python, также этот параметр, который позволяет вам использовать его как библиотеку в python: github.com/jalan/pdftotext

ocean800 23.06.2020 00:38

pyPDF отлично работает (при условии, что вы работаете с правильно сформированными PDF-файлами). Если вам нужен только текст (с пробелами), вы можете просто сделать:

import pyPdf
pdf = pyPdf.PdfFileReader(open(filename, "rb"))
for page in pdf.pages:
    print page.extractText()

Вы также можете легко получить доступ к метаданным, данным изображений и т. д.

Комментарий в примечаниях к коду extractText:

Locate all text drawing commands, in the order they are provided in the content stream, and extract the text. This works well for some PDF files, but poorly for others, depending on the generator used. This will be refined in the future. Do not rely on the order of text coming out of this function, as it will change if this function is made more sophisticated.

Является ли это проблемой, зависит от того, что вы делаете с текстом (например, если порядок не имеет значения, все в порядке, или если генератор добавляет текст в поток в том порядке, в котором он будет отображаться, это нормально) . У меня есть код извлечения pyPdf в повседневном использовании, без каких-либо проблем.

нет поддержки юникода :(

PanosJee 14.10.2010 14:30

pyPdf теперь поддерживает UTF.

lbolla 18.10.2012 20:19

Эта библиотека похожа на мусор. При тестировании случайного PDF-файла возникает ошибка «pyPdf.utils.PdfReadError: маркер EOF не найден»

Cerin 29.10.2012 18:59

Из вопроса: сгенерированный текст не имел пробелов и бесполезен. Я использовал pyPDF и получил тот же результат - текст извлекается без пробелов между словами.

Jordan Reiter 03.12.2012 21:45

Когда я выполняю функцию page.extractText (), я получаю сообщение об ошибке «TypeError: не могу неявно преобразовать объект« bytes »в str» Как я могу с этим справиться?

juankysmith 11.11.2013 13:55

Подтверждено - нет пробела между текстом. Что, черт возьми ... Я думаю, что эта библиотека подходит только для изменения размера, обрезки, переупорядочивания и т. д. PDFminer кажется лучшим выбором. В Windows я использую получил эти функции через (не бесплатный) Acrobat Pro (через его немного неудобный Javascript SDK), поэтому, хотя он и не достаточно хорош для текста, он кажется хорошим программным обеспечением.

Louis Maddox 21.05.2014 23:46

Я получаю, что объект ConvertFunctionsToVirtualList не вызывается

duhaime 10.03.2015 18:48

как получить соответствующие пробелы между ними, вывод выглядит неаккуратно?

lazarus 01.04.2015 13:10

Ссылка, показанная выше, показывает, что проект больше не поддерживается, а ссылка на github нового автора возвращает 404. Устаревший! «Эта страница больше не обновляется. Я прекратил поддерживать pyPdf, и компания Phaseit разделила проект и продолжила разработку и сопровождение с моего благословения как pyPdf2 (knowah.github.com/PyPDF2)». Я думаю, что за этот ответ, вероятно, следует проголосовать против, чтобы переместить его вниз по странице.

Dave Remy 27.06.2017 16:53

extractText () имеет проблемы. Это работает не для всех документов. Обновите код, если у вас есть стабильное решение.

Eswar 17.12.2019 11:29

Предлагаем использовать pyPDF2 согласно сообщению SO https://stackoverflow.com/questions/42130504/unable-to-use-p‌ ypdf-module

shyam 18.01.2021 08:15

Кроме того, существует PDFTextStream, коммерческая библиотека Java, которую также можно использовать из Python.

Вы также можете легко использовать pdfminer в качестве библиотеки. У вас есть доступ к модели содержимого PDF-файла и вы можете создавать свои собственные извлечения текста. Я сделал это, чтобы преобразовать содержимое PDF в текст, разделенный точкой с запятой, используя приведенный ниже код.

Функция просто сортирует объекты содержимого TextItem в соответствии с их координатами y и x и выводит элементы с той же координатой y, что и одна текстовая строка, разделяя объекты в одной строке с помощью ';' символы.

Используя этот подход, я смог извлечь текст из PDF-файла, из которого ни один другой инструмент не смог извлечь контент, пригодный для дальнейшего анализа. Другие инструменты, которые я пробовал, включают pdftotext, ps2ascii и онлайн-инструмент pdftextonline.com.

pdfminer - бесценный инструмент для очистки PDF-файлов.


def pdf_to_csv(filename):
    from pdflib.page import TextItem, TextConverter
    from pdflib.pdfparser import PDFDocument, PDFParser
    from pdflib.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item.objs:
                if isinstance(child, TextItem):
                    (_,_,x,y) = child.bbox
                    line = lines[int(-y)]
                    line[x] = child.text

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, "ascii")

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(doc, fp)
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

ОБНОВИТЬ:

Приведенный выше код написан для старой версии API, см. Мой комментарий ниже.

Какие плагины вам нужны, чтобы это работало, товарищ? Скачал и установил pdfminer, но этого мало ...

kxk 24.07.2011 21:38

Приведенный выше код написан для старой версии PDFminer. API был изменен в более поздних версиях (например, пакет теперь pdfminer, а не pdflib). Я предлагаю вам взглянуть на исходный код pdf2txt.py в исходнике PDFminer, приведенный выше код был вдохновлен старой версией этого файла.

codeape 25.07.2011 10:04

Пакет PDFMiner был изменен с момента публикации кодовая лента.

ИЗМЕНИТЬ (снова):

PDFMiner снова обновлен в версии 20100213

Вы можете проверить версию, которую вы установили, следующим образом:

>>> import pdfminer
>>> pdfminer.__version__
'20100213'

Вот обновленная версия (с комментариями о том, что я изменил / добавил):

def pdf_to_csv(filename):
    from cStringIO import StringIO  #<-- added so you can copy/paste this to try it
    from pdfminer.converter import LTTextItem, TextConverter
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item.objs:
                if isinstance(child, LTTextItem):
                    (_,_,x,y) = child.bbox                   #<-- changed
                    line = lines[int(-y)]
                    line[x] = child.text.encode(self.codec)  #<-- changed

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, codec = "utf-8")  #<-- changed 
        # becuase my test documents are utf-8 (note: utf-8 is the default codec)

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(fp)       #<-- changed
    parser.set_document(doc)     #<-- added
    doc.set_parser(parser)       #<-- added
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

Изменить (еще раз):

Вот обновление для последней версии в Pypi, 20100619p1. Короче говоря, я заменил LTTextItem на LTChar и передал экземпляр LAParams конструктору CsvConverter.

def pdf_to_csv(filename):
    from cStringIO import StringIO  
    from pdfminer.converter import LTChar, TextConverter    #<-- changed
    from pdfminer.layout import LAParams
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item.objs:
                if isinstance(child, LTChar):               #<-- changed
                    (_,_,x,y) = child.bbox                   
                    line = lines[int(-y)]
                    line[x] = child.text.encode(self.codec)

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, codec = "utf-8", laparams=LAParams())  #<-- changed
        # becuase my test documents are utf-8 (note: utf-8 is the default codec)

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(fp)       
    parser.set_document(doc)     
    doc.set_parser(parser)       
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        if page is not None:
            interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

РЕДАКТИРОВАТЬ (еще раз):

Обновлено для версии 20110515 (спасибо Oeufcoque Penteano!):

def pdf_to_csv(filename):
    from cStringIO import StringIO  
    from pdfminer.converter import LTChar, TextConverter
    from pdfminer.layout import LAParams
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter

    class CsvConverter(TextConverter):
        def __init__(self, *args, **kwargs):
            TextConverter.__init__(self, *args, **kwargs)

        def end_page(self, i):
            from collections import defaultdict
            lines = defaultdict(lambda : {})
            for child in self.cur_item._objs:                #<-- changed
                if isinstance(child, LTChar):
                    (_,_,x,y) = child.bbox                   
                    line = lines[int(-y)]
                    line[x] = child._text.encode(self.codec) #<-- changed

            for y in sorted(lines.keys()):
                line = lines[y]
                self.outfp.write(";".join(line[x] for x in sorted(line.keys())))
                self.outfp.write("\n")

    # ... the following part of the code is a remix of the 
    # convert() function in the pdfminer/tools/pdf2text module
    rsrc = PDFResourceManager()
    outfp = StringIO()
    device = CsvConverter(rsrc, outfp, codec = "utf-8", laparams=LAParams())
        # becuase my test documents are utf-8 (note: utf-8 is the default codec)

    doc = PDFDocument()
    fp = open(filename, 'rb')
    parser = PDFParser(fp)       
    parser.set_document(doc)     
    doc.set_parser(parser)       
    doc.initialize('')

    interpreter = PDFPageInterpreter(rsrc, device)

    for i, page in enumerate(doc.get_pages()):
        outfp.write("START PAGE %d\n" % i)
        if page is not None:
            interpreter.process_page(page)
        outfp.write("END PAGE %d\n" % i)

    device.close()
    fp.close()

    return outfp.getvalue()

In [6]: import pdfminer In [7]: pdfminer .__ version__ Out [7]: '20100424' In [8]: from pdfminer.converter import LTTextItem ImportError: не удается импортировать имя LTTextItem .... LITERALS_DCT_DECODE LTChar LTImage LTPolygon LTText LTContainer LTLine LTRect LTTextGroup LITERAL_DEVICE_RGB LTFigure LTPage LTText LTTextLine

Skylar Saveland 18.07.2010 02:41

@skyl, приведенный выше код относится к предыдущей версии 20100213. Судя по списку изменений на их веб-сайте, похоже, они изменили LTTextItem на LTChar. unixuser.org/~euske/python/pdfminer/index.html#changes

tgray 19.07.2010 17:17

Если кто-то столкнется с этим постом, который нуждается в приличном способе чтения построчно PDF-файлов, как я хотел и не смог сделать в самой последней версии, очень незначительные изменения в этом коде сделают его работоспособным в 20110515: Линия dir, чтобы увидеть, что происходит, сделала все возможное. В строке 19 измените for child in self.cur_item.objs: на for child in self.cur_item._objs: (просто добавьте подчеркивание к objs); и в строке 23 сделайте то же самое для text, то есть: line[x] = child.text.encode(self.codec) должен измениться на line[x] = child._text.encode(self.codec)

Oeufcoque Penteano 16.06.2013 02:12

См. Также unixuser.org/~euske/python/pdfminer/programming.html

Oeufcoque Penteano 16.06.2013 02:13

@Oeufcoque Penteano, спасибо! Я добавил еще один раздел к ответу для версии 20110515 на ваш комментарий.

tgray 25.06.2013 23:10

Жаль, что мне пришлось использовать для этого другой инструмент, который не является открытым исходным кодом (хотя и бесплатный), для предварительной обработки части pdf. Вы знаете, можно ли восстановить белые пространства с помощью pdfminer? Все символы разделяются символом ";" из этой версии кода, но пробелы не появляются. Мне бы очень хотелось, если бы я мог перейти на версию с открытым исходным кодом :)

Oeufcoque Penteano 26.06.2013 23:15

последняя версия работает, но после каждого символа стоит точка с запятой, я много чего пробовал, но не смог исправить. есть идеи, как этого избежать?

voldyman 30.06.2013 16:05

Мне кажется, что pdfminer - не решение, так как он ломает код при каждом изменении! Также отсутствует хорошая документация, в то время как ссылка для скачивания на "официальной" странице ссылается только на ее собственную!

Rafael T 31.01.2014 23:50

Ответ @ user3272884 работает по состоянию на 01.05.2014.

jmunsch 02.05.2014 08:15

Мне пришлось сегодня решить эту же проблему, немного изменил код tgray для извлечения информации о пробелах, выложил здесь

tarikki 29.04.2016 13:28

Почему бы просто не опубликовать это на Github?

qodeninja 04.08.2017 00:35

API PDFminer снова изменился. Теперь есть форк pdfminer.six Вот рабочий пример от мая 2020 года. from pdfminer.high_level import extract_text, затем text = extract_text('report.pdf')stackoverflow.com/a/61857301/7483211

Cornelius Roemer 17.05.2020 22:14

Переназначение кода pdf2txt.py, поставляемого с pdfminer; вы можете создать функцию, которая будет указывать путь к pdf; необязательно, outtype (txt | html | xml | tag) и выбирает как командную строку pdf2txt {'-o': '/path/to/outfile.txt' ...}. По умолчанию вы можете вызвать:

convert_pdf(path)

Будет создан текстовый файл, аналог в файловой системе исходного PDF-файла.

def convert_pdf(path, outtype='txt', opts = {}):
    import sys
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter, process_pdf
    from pdfminer.converter import XMLConverter, HTMLConverter, TextConverter, TagExtractor
    from pdfminer.layout import LAParams
    from pdfminer.pdfparser import PDFDocument, PDFParser
    from pdfminer.pdfdevice import PDFDevice
    from pdfminer.cmapdb import CMapDB

    outfile = path[:-3] + outtype
    outdir = '/'.join(path.split('/')[:-1])

    debug = 0
    # input option
    password = ''
    pagenos = set()
    maxpages = 0
    # output option
    codec = 'utf-8'
    pageno = 1
    scale = 1
    showpageno = True
    laparams = LAParams()
    for (k, v) in opts:
        if k == '-d': debug += 1
        elif k == '-p': pagenos.update( int(x)-1 for x in v.split(',') )
        elif k == '-m': maxpages = int(v)
        elif k == '-P': password = v
        elif k == '-o': outfile = v
        elif k == '-n': laparams = None
        elif k == '-A': laparams.all_texts = True
        elif k == '-D': laparams.writing_mode = v
        elif k == '-M': laparams.char_margin = float(v)
        elif k == '-L': laparams.line_margin = float(v)
        elif k == '-W': laparams.word_margin = float(v)
        elif k == '-O': outdir = v
        elif k == '-t': outtype = v
        elif k == '-c': codec = v
        elif k == '-s': scale = float(v)
    #
    CMapDB.debug = debug
    PDFResourceManager.debug = debug
    PDFDocument.debug = debug
    PDFParser.debug = debug
    PDFPageInterpreter.debug = debug
    PDFDevice.debug = debug
    #
    rsrcmgr = PDFResourceManager()
    if not outtype:
        outtype = 'txt'
        if outfile:
            if outfile.endswith('.htm') or outfile.endswith('.html'):
                outtype = 'html'
            elif outfile.endswith('.xml'):
                outtype = 'xml'
            elif outfile.endswith('.tag'):
                outtype = 'tag'
    if outfile:
        outfp = file(outfile, 'w')
    else:
        outfp = sys.stdout
    if outtype == 'txt':
        device = TextConverter(rsrcmgr, outfp, codec=codec, laparams=laparams)
    elif outtype == 'xml':
        device = XMLConverter(rsrcmgr, outfp, codec=codec, laparams=laparams, outdir=outdir)
    elif outtype == 'html':
        device = HTMLConverter(rsrcmgr, outfp, codec=codec, scale=scale, laparams=laparams, outdir=outdir)
    elif outtype == 'tag':
        device = TagExtractor(rsrcmgr, outfp, codec=codec)
    else:
        return usage()

    fp = file(path, 'rb')
    process_pdf(rsrcmgr, device, fp, pagenos, maxpages=maxpages, password=password)
    fp.close()
    device.close()

    outfp.close()
    return

Я использовал pdftohtml с аргументом -xml, прочитайте результат с помощью subprocess.Popen(), который даст вам координату x, координату y, ширину, высоту и шрифт для каждого фрагмент текста в pdf. Я думаю, что это то, что, вероятно, использует и 'evince', потому что одни и те же сообщения об ошибках извергаются.

Если вам нужно обрабатывать столбчатые данные, это становится немного сложнее, так как вам нужно изобрести алгоритм, который подходит для вашего файла pdf. Проблема в том, что программы, создающие файлы PDF, на самом деле не обязательно размещают текст в каком-либо логическом формате. Вы можете попробовать простые алгоритмы сортировки, и это иногда срабатывает, но могут быть небольшие «отставшие» и «заблудшие» фрагменты текста, которые не помещаются в том порядке, в котором вы предполагали. Так что вам нужно проявить творческий подход.

Мне потребовалось около 5 часов, чтобы придумать один для PDF-файла, над которым я работал. Но сейчас это работает неплохо. Удачи.

Нашел это решение сегодня. У меня отлично работает. Рендеринг страниц PDF в изображения PNG. http://www.swftools.org/gfx_tutorial.html

slate - это проект, который упрощает использование PDFMiner из библиотеки:

>>> with open('example.pdf') as f:
...    doc = slate.PDF(f)
...
>>> doc
[..., ..., ...]
>>> doc[1]
'Text from page 2...'   

Я получаю сообщение об ошибке импорта при выполнении "import slate": {File "C: \ Python33 \ lib \ site-packages \ slate-0.3-py3.3.egg \ slate_ini‌ t_.py", строка 48, в ImportError: невозможно импортировать имя PDF} Но класс PDF есть! Вы знаете, как это решить?

juankysmith 11.11.2013 14:14

Нет, это звучит очень странно. У вас есть зависимости?

Tim McNamara 11.11.2013 20:50

Обычно я получаю сообщения о пропущенных зависимостях, в этом случае я получаю классическое сообщение "import slate File" C: \ Python33 \ lib \ site-packages \ slate-0.3-py3.3.egg \ slate_ini‌ t_.py ", строка 48, в ImportError: невозможно импортировать имя PDF "

juankysmith 12.11.2013 11:42

Slate 0.3 требует pdfminer 20110515, согласно этому Проблема с GitHub

jabbett 07.11.2014 19:04

Этот пакет больше не поддерживается. Воздержитесь от его использования. Вы даже не можете использовать его в Python 3.5

Sivasubramaniam Arunachalam 06.01.2017 18:32

Мне нужно было преобразовать конкретный PDF-файл в обычный текст в модуле Python. Я использовал PDFMiner 20110515, прочитав их инструмент pdf2txt.py, я написал этот простой фрагмент:

from cStringIO import StringIO
from pdfminer.pdfinterp import PDFResourceManager, process_pdf
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams

def to_txt(pdf_path):
    input_ = file(pdf_path, 'rb')
    output = StringIO()

    manager = PDFResourceManager()
    converter = TextConverter(manager, output, laparams=LAParams())
    process_pdf(manager, converter, input_)

    return output.getvalue() 

def to_txt (pdf_path):

Cătălin George Feștilă 25.10.2013 13:58

если бы я хотел преобразовать только определенное количество страниц, как бы я сделал это с помощью этого кода?

psychok7 03.04.2014 12:18

@ psychok7 Вы пробовали использовать инструмент pdf2txt? Кажется, эта функция поддерживается в текущей версии с флагом -p, реализация кажется простой и легко настраивается: github.com/euske/pdfminer/blob/master/tools/pdf2txt.py Надеюсь, это поможет! :)

gonz 03.04.2014 23:45

спасибо @gonz, я пробовал все вышеперечисленное, но ваше решение оказалось идеальным для меня, вывод с пробелами :)

lazarus 14.04.2015 09:30

pdf2txt.py установлен здесь для меня: C:\Python27\Scripts\pdfminer\tools\pdf2txt.py

The Red Pea 14.09.2015 23:52

Поскольку ни одно из этих решений не поддерживает последнюю версию PDFMiner, я написал простое решение, которое будет возвращать текст PDF-файла с помощью PDFMiner. Это будет работать для тех, у кого возникают ошибки импорта с process_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
from cStringIO import StringIO

def pdfparser(data):

    fp = file(data, 'rb')
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()
    codec = 'utf-8'
    laparams = LAParams()
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    # Create a PDF interpreter object.
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    # Process each page contained in the document.

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

    print data

if __name__ == '__main__':
    pdfparser(sys.argv[1])  

См. Ниже код, который работает для Python 3:

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)
    # Create a PDF interpreter object.
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    # Process each page contained in the document.

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

    print(data)

if __name__ == '__main__':
    pdfparser(sys.argv[1])  

это первый найденный мной фрагмент, который действительно работает со странными файлами PDF (особенно с бесплатными электронными книгами, которые можно получить на packtpub). Любой другой фрагмент кода просто возвращает странно закодированный необработанный материал, но ваш на самом деле возвращает текст. Спасибо!

somada141 30.01.2016 04:42

Вероятно, вы захотите выполнить retstr.seek (0) после получения данных, иначе вы накопите текст со всех страниц.

Tshirtman 01.03.2017 21:01

Для использования с python3, помимо очевидных скобок после команды print, необходимо заменить команду file на open и импортировать StringIO из пакета io.

McLawrence 03.07.2017 18:34

Вау. Этот блок отлично работал с первого раза, когда я его скопировал. Потрясающе! Переходим к синтаксическому анализу и исправлению данных, а также к тому, чтобы не беспокоиться о вводе.

SecsAndCyber 07.07.2017 04:18

pdfminer не работает с python3. этот код не работает для pdfminer3k

thang 15.09.2017 21:50

как использовать его для лямбда aws, при использовании он показывает ошибку импорта error

Arun Kumar 27.02.2018 10:32

Это единственный ответ, который работает.

gented 13.10.2018 00:23

У меня есть файл PDF, который я хочу прочитать, как мне назначить его переменной data?

Thelonious Monk 23.09.2019 18:47

Другие вопросы по теме