بيثون وحدة لتحويل PDF إلى نص [مغلقة]
-
09-06-2019 - |
سؤال
والتي هي أفضل الثعبان وحدات لتحويل ملفات 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