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


    byte[] data;
                using (WebClient client = new WebClient())
                {
                  ICredentials cred;
                  cred = new NetworkCredential("xmen@test.com", "mybestpassword");
                  client.Proxy = new WebProxy("192.168.0.1",8000);
                  client.Credentials = cred;
                  string myurl="http://mytestsite.com/source.jpg";
                  data = client.DownloadData(myUrl);
               }

          File.WriteAllBytes(@"c:\images\target.jpg", data);

370
задан adamk 10 July 2017 в 06:40
поделиться

8 ответов

Попробуйте PDFMiner. Это может извлечь текст из файлов PDF как HTML, SGML или "Теговый PDF" формат.

Теговый формат PDF, кажется, является самым чистым, и снятие XML-тэгов оставляет просто пустой текст.

А версия Python 3 доступна под:

134
ответ дан Felipe Augusto 10 July 2017 в 06:40
поделиться
  • 1
    That' s гораздо дальше по линии. Неважно, что Вы делаете, you' ре, все еще собирающееся нуждаться в системе как те выше для классификации всех этих агентов и необходимого AI. – Sneakyness 7 August 2009 в 04:42

pyPDF хорошо работает (предполагающий, что Вы работаете с правильно построенным PDFs). Если все, что Вы хотите, является текстом (с пробелами), можно просто сделать:

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

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

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

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

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

42
ответ дан Tony Meyer 10 July 2017 в 06:40
поделиться

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

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

видят мой вопрос для того, на что похож вывод pdftoipe.

1
ответ дан Community 10 July 2017 в 06:40
поделиться
  • 1
    Я согласился бы здесь - если Ваша хранимая процедура ETL занимает слишком много времени (т.е. больше, чем несколько минут?) тогда Вы хотели бы рассмотреть SSIS как альтернативу по причинам производительности.:) – Mayo 20 November 2009 в 21:57

Pdftotext программа с открытым исходным кодом (часть Xpdf), который Вы могли назвать из Python (не, что Вы попросили, но могли бы быть полезными). Я использовал его без проблем. Я думаю, что Google использует его в рабочем столе Google.

46
ответ дан Jamie 10 July 2017 в 06:40
поделиться

Можно также довольно легко использовать 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, см. мой комментарий ниже.

21
ответ дан codeape 10 July 2017 в 06:40
поделиться

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

1
ответ дан msanders 10 July 2017 в 16:40
поделиться
  • 1
    I' m работающий в моем первом карьерном задании и имею дело с балансом хранимых процедур и ssis. И я испытываю каждые из этих соображений. – eddiecubed 22 February 2014 в 04:15

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

РЕДАКТИРОВАТЬ (снова):

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()
135
ответ дан 22 November 2019 в 23:59
поделиться

Переделка кода 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
5
ответ дан 22 November 2019 в 23:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: