سؤال

والتي هي أفضل الثعبان وحدات لتحويل ملفات PDF إلى النص ؟

هل كانت مفيدة؟

المحلول

محاولة PDFMiner.فإنه يمكن استخراج النص من ملفات PDF HTML SGML أو "معلم PDF" تنسيق.

الموسومة PDF يبدو أن أنظف و تجريد من علامات XML الأوراق فقط العارية النص.

بيثون 3 الإصدار هو متاح تحت:

نصائح أخرى

على 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()

لأن أيا من أجل هذه الحلول دعم أحدث نسخة من 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])  

انظر أدناه التعليمات البرمجية التي تعمل بيثون 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])  

Pdftotext برنامج مفتوح المصدر (جزء من Xpdf) التي يمكنك الاتصال من بيثون (لا ما طلبت ولكن قد تكون مفيدة).لقد استخدامه مع أي مشاكل.أعتقد أن جوجل استخدامه في جوجل سطح المكتب.

pyPDF يعمل بشكل جيد (على افتراض أنك تعمل بشكل جيد Pdf).إذا كان كل ما تريده هو النص (مع المسافات) ، يمكنك القيام به فقط:

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

يمكنك أيضا بسهولة الحصول على البيانات, بيانات الصورة ، وهكذا دواليك.

تعليق في extractText رمز ملاحظات:

تحديد موقع كل نص الأوامر الرسم ، الترتيب الذي تقدم في بث المحتوى و استخراج النص.هذا يعمل بشكل جيد على بعض ملفات PDF ، ولكن سيئة للآخرين ، اعتمادا على المولدات المستخدمة.هذا سوف يكون دقة في المستقبل.لا تعتمد على ترتيب النص يخرج من هذا وظيفة, كما أنها سوف تتغير إذا كان هذا وظيفة أكثر تطورا.

ما إذا كان هذا هو مشكلة يعتمد على ما تفعله مع النص (مثلا ، إذا كان النظام لا يهم, لا بأس, أو إذا كان مولد يضيف النص إلى تيار في النظام وسيتم عرض بأس).لدي pyPdf استخراج التعليمات البرمجية في الاستخدام اليومي ، من دون أي مشاكل.

يمكنك أيضا بسهولة تامة استخدام 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 انظر التعليق أدناه.

slate هو المشروع الذي يجعل من السهل جدا استخدام PDFMiner من المكتبة:

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

أنا في حاجة لتحويل معين PDF إلى نص عادي في بيثون وحدة.اعتدت 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() 

أخرى على pdf2txt.py التعليمات البرمجية التي تأتي مع pdfminer;يمكنك جعل وظيفة من شأنها أن تأخذ الطريق إلى pdf.اختياريا ، outtype (txt|html|xml|الوسم) و اختار مثل فلكس 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

PDFminer أعطاني ربما سطر واحد [صفحة 1 من 7...] على كل صفحة من ملف pdf حاولت معها.

أفضل جواب حتى الآن هو pdftoipe ، أو c++ code أنها تقوم على Xpdf.

انظر سؤالي لما خرج من pdftoipe يبدو.

بالإضافة إلى ذلك هناك PDFTextStream وهو التجارية جافا المكتبة التي يمكن أن تستخدم أيضا من بيثون.

لقد استخدمت pdftohtml مع -xml الحجة قراءة النتيجة مع subprocess.Popen(), هذا وسوف تعطيك x coord ، ص coord, عرض, ارتفاع, والخط, كل مقتطف النص في pdf.وأعتقد أن هذا هو ما يبدي' ربما يستخدم أيضا لأن نفس رسائل الخطأ يقذف بها.

إذا كنت بحاجة إلى عملية عمودي البيانات ، فإنه يحصل قليلا أكثر تعقيدا كما يجب أن ابتكار خوارزمية التي تناسب ملف pdf.المشكلة هي أن البرامج التي تجعل من ملفات PDF لا بالضرورة وضع النص في أي شكل منطقي.يمكنك محاولة بسيطة خوارزميات الفرز و يعمل في بعض الأحيان, ولكن يمكن أن يكون هناك قليلا 'المتطرفون" و "الشوارد', قطعة من النص أن لا أوضع في الأمر كنت أعتقد أنها سوف.لذلك عليك أن تكون مبدعا.

استغرق مني حوالي 5 ساعات لمعرفة واحد pdf كنت تعمل على.لكنه يعمل بشكل جيد الآن.حظا سعيدا.

وجدت أن الحل اليوم.يعمل كبيرة بالنسبة لي.حتى جعل صفحات PDF على الصور بابوا نيو غينيا.http://www.swftools.org/gfx_tutorial.html

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top