PDF dosyalarını metne dönüştürmek için herhangi bir python modülü var mı? Pypdf kullanan Activestate bulunan bir kod parçası denedim ama oluşturulan metin arasında boşluk vardı ve hiçbir faydası yoktu.
PDF dosyalarını metne dönüştürmek için herhangi bir python modülü var mı? Pypdf kullanan Activestate bulunan bir kod parçası denedim ama oluşturulan metin arasında boşluk vardı ve hiçbir faydası yoktu.
Yanıtlar:
PDFMiner'ı deneyin . PDF dosyalarından HTML, SGML veya "Etiketli PDF" formatında metin ayıklayabilirsiniz.
Etiketli PDF formatı en temiz gibi görünüyor ve XML etiketlerini çıkarmak sadece çıplak metin bırakıyor.
Bir Python 3 sürümü aşağıdaki adreslerde mevcuttur:
PDFMiner beri paket değişti codeape yayınlanmıştır.
DÜZENLE (tekrar):
PDFMiner sürümde tekrar güncellendi 20100213
Yüklediğiniz sürümü aşağıdakilerle kontrol edebilirsiniz:
>>> import pdfminer
>>> pdfminer.__version__
'20100213'
İşte güncellenmiş sürüm (değiştirdiğim / eklediğim yorumlarla):
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()
Düzenle (yine):
İşte son sürümü için bir güncelleme olup pypi , 20100619p1
. Kısacası ben değiştirilir LTTextItem
ile LTChar
ve CsvConverter yapıcısına LAParams bir örneğini geçti.
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()
DÜZENLE (bir kez daha):
Sürüm için güncellendi 20110515
(Oeufcoque Penteano sayesinde!):
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()
LTTextItem
üzere LTChar
. unixuser.org/~euske/python/pdfminer/index.html#changes
20110515
.
Bu çözümler için hiçbiri PDFMiner'ın en son sürümünü desteklemediğinden, PDFMiner kullanarak bir pdf metni döndürecek basit bir çözüm yazdım. Bu, ithalat hataları alan kişiler için işe yararprocess_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 için çalışan aşağıdaki koda bakın:
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])
python3
, sonra bariz parantez yanında print
yerini alacak komuta, birine sahiptir file
ile komut open
ve ithalat StringIO
paketindenio
Pdftotext Python'dan arayabileceğiniz bir açık kaynak programı ( Xpdf'nin bir parçası) (istediğinizi değil, yararlı olabilir). Ben sorunsuz kullandım. Ben google google masaüstü kullanmak düşünüyorum.
-layout
metni PDF'deki ile aynı konumda tutma seçeneği. Şimdi, bir PDF'nin içeriğini içine nasıl aktaracağımı anlayabilseydim.
pdftotext
çok iyi çalışıyor gibi görünüyor, ancak stdout'ta sonuçları görmek istiyorsanız, kısa çizgi olan ikinci bir argümana ihtiyacı var.
find . -iname "*.pdf" -exec pdftotext -enc UTF-8 -eol unix -raw {} \;
Varsayılan olarak, oluşturulan dosyalar orijinal adı .txt
uzantıyla alır.
pyPDF iyi çalışıyor (iyi biçimlendirilmiş PDF'lerle çalıştığınızı varsayarak). İstediğiniz tek şey metinse (boşluklu), şunları yapabilirsiniz:
import pyPdf
pdf = pyPdf.PdfFileReader(open(filename, "rb"))
for page in pdf.pages:
print page.extractText()
Ayrıca meta verilere, görüntü verilerine vb. Kolayca erişebilirsiniz.
ExtractText kodundaki bir açıklama notları:
Tüm metin çizim komutlarını içerik akışında sağlandıkları sırayla bulun ve metni çıkarın. Bu, bazı PDF dosyaları için iyi çalışır, ancak kullanılan jeneratöre bağlı olarak diğerleri için kötüdür. Bu gelecekte rafine edilecektir. Bu fonksiyondan çıkan metnin sırasına güvenmeyin, çünkü bu fonksiyon daha sofistike hale gelirse değişecektir.
Bunun bir sorun olup olmadığı metinle ne yaptığınıza bağlıdır (örneğin, sipariş önemli değilse, sorun değil veya oluşturucu akışa görüntüleneceği sırayla metin eklerse sorun yok) . Herhangi bir sorun olmadan günlük kullanımda pyPdf çıkarma kodu var.
Ayrıca pdfminer'ı kütüphane olarak da kullanabilirsiniz. PDF'nin içerik modeline erişiminiz vardır ve kendi metin çıkartma işleminizi oluşturabilirsiniz. Bunu, aşağıdaki kodu kullanarak pdf içeriğini noktalı virgülle ayrılmış metne dönüştürmek için yaptım.
İşlev TextItem içerik nesnelerini y ve x koordinatlarına göre sıralar ve aynı satırdaki nesneleri ';' ile ayırarak bir metin satırıyla aynı y koordinatına sahip öğeler çıkarır. karakter.
Bu yaklaşımı kullanarak, başka bir aracın daha fazla ayrıştırma için uygun içeriği çıkaramadığı bir pdf'den metin çıkarabildim. Denediğim diğer araçlar arasında pdftotext, ps2ascii ve pdftextonline.com çevrimiçi aracı sayılabilir.
pdfminer, pdf-kazıma için paha biçilmez bir araçtır.
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()
GÜNCELLEME :
Yukarıdaki kod, API'nın eski bir sürümüne göre yazılmıştır, aşağıdaki yorumuma bakın.
pdfminer
değil pdflib
). pdf2txt.py
PDFminer kaynağının kaynağına bir göz atmanızı öneririm, yukarıdaki kod bu dosyanın eski sürümünden esinlenmiştir.
slate
PDFMiner'ı bir kütüphaneden kullanmayı çok kolaylaştıran bir projedir:
>>> with open('example.pdf') as f:
... doc = slate.PDF(f)
...
>>> doc
[..., ..., ...]
>>> doc[1]
'Text from page 2...'
Belirli bir PDF'yi bir python modülünde düz metne dönüştürmem gerekiyordu. PDFMiner 20110515 kullandım , pdf2txt.py aracını okuduktan sonra bu basit parçacığı yazdım:
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()
C:\Python27\Scripts\pdfminer\tools\pdf2txt.py
Pdfminer ile gelen pdf2txt.py kodunu değiştirme; pdf yolunu alacak bir işlev yapabilirsiniz; isteğe bağlı olarak bir outtype (txt | html | xml | tag) ve pdf2txt {'-o': '/path/to/outfile.txt' ...} komut satırını seçer. Varsayılan olarak şunları arayabilirsiniz:
convert_pdf(path)
Dosya sisteminde orijinal pdf'ye kardeş olan bir metin dosyası oluşturulacaktır.
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 onunla denediğim bir pdf dosyasının her sayfasında bana belki bir satır [sayfa 1/7 ...] verdi.
Şimdiye kadar sahip olduğum en iyi cevap pdftoipe veya Xpdf tabanlı c ++ kodudur.
bkz sorumu pdftoipe görünüyor çıktısı gibi ne için.
Ayrıca Python'dan da kullanılabilen ticari bir Java kütüphanesi olan PDFTextStream var .
Ben kullandım pdftohtml
ile -xml
birlikte sonucu okuyun, argüman subprocess.Popen()
bu sana x coord y coord, genişlik, yükseklik ve yazı tipi verecek her arasında pasajı metin . Bence bu 'evince' muhtemelen de kullanır çünkü aynı hata mesajları seslenir.
Sütunlu verileri işlemeniz gerekiyorsa, pdf dosyanıza uygun bir algoritma icat etmeniz gerektiğinden biraz daha karmaşık hale gelir. Sorun, PDF dosyalarını oluşturan programların metni gerçekten herhangi bir mantıksal formatta yerleştirmemesidir. Basit sıralama algoritmalarını deneyebilirsiniz ve bazen çalışır, ancak küçük 'stragglers' ve 'strays', düşündüğünüz sıraya göre yerleştirilmeyen metin parçaları olabilir. Yani yaratıcı olmalısınız.
Üzerinde çalıştığım pdf'ler için bir tane bulmak yaklaşık 5 saatimi aldı. Ama şimdi oldukça iyi çalışıyor. İyi şanslar.
Bugün bu çözümü buldum. Benim için harika çalışıyor. Hatta PDF sayfalarını PNG görüntülerine dönüştürmek. http://www.swftools.org/gfx_tutorial.html