পিডিএফ ফাইলগুলিকে পাঠ্যে রূপান্তর করার জন্য কি অজগর মডিউল রয়েছে? আমি অ্যাক্টিস্টেটে পাওয়া কোডের এক টুকরো চেষ্টা করেছি যা পাইপডিএফ ব্যবহার করে তবে উত্পন্ন পাঠ্যের কোনও স্থান নেই এবং এর কোনও ব্যবহার ছিল না।
পিডিএফ ফাইলগুলিকে পাঠ্যে রূপান্তর করার জন্য কি অজগর মডিউল রয়েছে? আমি অ্যাক্টিস্টেটে পাওয়া কোডের এক টুকরো চেষ্টা করেছি যা পাইপডিএফ ব্যবহার করে তবে উত্পন্ন পাঠ্যের কোনও স্থান নেই এবং এর কোনও ব্যবহার ছিল না।
উত্তর:
পিডিএফমিনার চেষ্টা করুন । এটি পিডিএফ ফাইল থেকে এইচটিএমএল, এসজিএমএল বা "ট্যাগযুক্ত পিডিএফ" ফর্ম্যাট হিসাবে পাঠ্য বের করতে পারে।
ট্যাগ করা পিডিএফ ফর্ম্যাটটি সবচেয়ে পরিষ্কার বলে মনে হচ্ছে এবং এক্সএমএল ট্যাগগুলি বের করে দেওয়া কেবল খালি পাঠ্যকে ছেড়ে যায়।
পাইথন 3 সংস্করণটি নীচে উপলব্ধ:
কোডপে পোস্ট হওয়ার পরে পিডিএফমিনার প্যাকেজ পরিবর্তন হয়েছে ।
সম্পাদনা (আবার):
সংস্করণে পিডিএফমিনার আবার আপডেট করা হয়েছে 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
এবং সিএভিসি কনভার্টর কনস্ট্রাক্টরের কাছে ল্যাপারামগুলির একটি উদাহরণ দিয়েছি।
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
(ওউফকো পেন্তানোকে ধন্যবাদ!):
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
হয়েছে LTChar
। unixuser.org/~euske/python/pdfminer/index.html#changes
20110515
আপনার মন্তব্য অনুযায়ী সংস্করণ জন্য উত্তরে অন্য বিভাগ যুক্ত করেছি ।
যেহেতু এই সমাধানগুলির জন্য কোনওই পিডিএফ মাইনারের সর্বশেষ সংস্করণকে সমর্থন করে না আমি একটি সহজ সমাধান লিখেছি যা পিডিএফ মাইনার ব্যবহার করে কোনও পিডিএফের পাঠ্য ফিরে আসবে। এটি যাঁদের সাথে আমদানি ত্রুটি পাচ্ছেন তাদের পক্ষে কাজ করবে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])
python3
, পরে সুস্পষ্ট প্রথম বন্ধনী ব্যতীত print
কমান্ড এক হয়েছে প্রতিস্থাপন file
সঙ্গে কমান্ড open
এবং আমদানি StringIO
প্যাকেজ থেকেio
পিডিফোটটেক্সট একটি ওপেন সোর্স প্রোগ্রাম (এক্সপিডিএফ এর অংশ) যা আপনি পাইথন থেকে কল করতে পারেন (আপনি যা চেয়েছিলেন তা নয় তবে কার্যকর হতে পারে)। আমি এটি কোনও সমস্যা ছাড়াই ব্যবহার করেছি। আমার মনে হয় গুগল এটি গুগল ডেস্কটপে ব্যবহার করে।
-layout
পাঠ্যকে একই অবস্থানে রাখার বিকল্প সহ । এখন যদি আমি বুঝতে পারি যে এটিতে কীভাবে পিডিএফের বিষয়বস্তুগুলি পাইপ করা যায়।
pdftotext
খুব ভাল কাজ করছে বলে মনে হচ্ছে, তবে এটি স্টিডআউটের ফলাফলগুলি দেখতে চাইলে এটির একটি দ্বিতীয় যুক্তি যা হাইফেন needs
find . -iname "*.pdf" -exec pdftotext -enc UTF-8 -eol unix -raw {} \;
ডিফল্টরূপে উত্পন্ন ফাইলগুলি .txt
এক্সটেনশনের সাথে আসল নাম নেয় ।
পিপিপিএফ সূক্ষ্মভাবে কাজ করে (ধরে নিবেন যে আপনি সু-গঠিত পিডিএফ নিয়ে কাজ করছেন)। যদি আপনি যা চান তা হ'ল পাঠ্য (স্পেস সহ), আপনি কেবল এটি করতে পারেন:
import pyPdf
pdf = pyPdf.PdfFileReader(open(filename, "rb"))
for page in pdf.pages:
print page.extractText()
আপনি মেটাডেটা, চিত্র ডেটা, এবং আরও সহজেই অ্যাক্সেস পেতে পারেন।
এক্সট্রাক্টেক্সট কোড নোটগুলিতে একটি মন্তব্য:
সমস্ত পাঠ্য অঙ্কন কমান্ড সন্ধান করুন, কন্টেন্ট স্ট্রিমে সরবরাহ করা ক্রম অনুযায়ী এবং পাঠ্যটি বের করুন। এটি কিছু পিডিএফ ফাইলের জন্য ভাল কাজ করে তবে অন্যটির জন্য খারাপ ব্যবহার করা জেনারেটরের উপর নির্ভর করে। ভবিষ্যতে এটি পরিমার্জন করা হবে। এই ফাংশনটি থেকে আসা পাঠ্যের ক্রমের উপর নির্ভর করবেন না, কারণ এই ফাংশনটি আরও পরিশীলিত করা হলে এটি পরিবর্তিত হবে।
সমস্যাটি কিনা তা আপনি পাঠ্যের সাহায্যে কী করছেন তার উপর নির্ভর করে (উদাঃ যদি অর্ডারটির কোনও ব্যাপার না হয় তবে তা ঠিক আছে, বা জেনারেটর প্রবাহে পাঠ্য যুক্ত করলে এটি প্রদর্শিত হবে, ঠিক আছে) । আমার প্রতিদিনের ব্যবহারে পাইপডিএফ এক্সট্রাকশন কোড রয়েছে, কোনও সমস্যা নেই।
আপনি খুব সহজেই একটি লাইব্রেরি হিসাবে পিডিএফমিনার ব্যবহার করতে পারেন। আপনি পিডিএফ এর সামগ্রী মডেল অ্যাক্সেস করতে পারেন এবং আপনার নিজের পাঠ্য নিষ্কাশন তৈরি করতে পারেন। নীচের কোডটি ব্যবহার করে আমি পিডিএফ সামগ্রীগুলি আধা-কোলন দ্বারা পৃথক করা পাঠ্যে রূপান্তর করতে করেছি did
ফাংশনটি কেবল তাদের y এবং x স্থানাঙ্ক অনুযায়ী টেক্সট আইটেম সামগ্রীকে বাছাই করে এবং একই y এর আইটেমগুলিকে একই পাঠ্য রেখার মতো স্থিত করে আউটপুট দেয়, এবং একই লাইনে অবজেক্টগুলিকে আলাদা করে দেয়; '; চরিত্র.
এই পদ্ধতির ব্যবহার করে, আমি কোনও পিডিএফ থেকে পাঠ্যটি বের করতে সক্ষম হয়েছি যে অন্য কোনও সরঞ্জাম এখান থেকে আরও পার্সিংয়ের জন্য উপযুক্ত সামগ্রী বের করতে সক্ষম ছিল না। অন্যান্য সরঞ্জামগুলির মধ্যে আমি চেষ্টা করেছি পিডিফোটটেক্সট, পিএস 2 এসসিআই এবং অনলাইন সরঞ্জাম pdftextonline.com।
পিডিএফমিনার পিডিএফ-স্ক্র্যাপিংয়ের জন্য একটি অমূল্য সরঞ্জাম।
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
, নেই pdflib
)। আমি আপনাকে pdf2txt.py
পিডিএফএমনির উত্সের উত্সটি দেখে পরামর্শ দিই, উপরের কোডটি সেই ফাইলটির পুরানো সংস্করণ দ্বারা অনুপ্রাণিত হয়েছিল।
slate
এটি এমন একটি প্রকল্প যা একটি লাইব্রেরি থেকে পিডিএফমিনার ব্যবহার করা খুব সহজ করে তোলে:
>>> with open('example.pdf') as f:
... doc = slate.PDF(f)
...
>>> doc
[..., ..., ...]
>>> doc[1]
'Text from page 2...'
পাইথন মডিউলের মধ্যে একটি নির্দিষ্ট পিডিএফকে সরল পাঠ্যে রূপান্তর করা দরকার to আমি পিডিএফমিনার 20110515 ব্যবহার করেছি , তাদের পিডিএফ 2 টেক্সট.পি সরঞ্জাম দিয়ে পড়ার পরে আমি এই সাধারণ স্নিপেটটি লিখেছিলাম:
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
পিডিএফ 2 টেক্সট.পি কোড যা পিডিএফমিনারের সাথে আসে তা পুনরায় পোস্ট করা; আপনি এমন একটি ফাংশন তৈরি করতে পারেন যা পিডিএফের দিকে এগিয়ে যাবে; allyচ্ছিকভাবে, একটি আউটটাইপ (txt | html | xML | ট্যাগ) এবং pdf2txt কমান্ডলাইন {'-o': '/path/to/outfile.txt' ...} এর মতো পছন্দ রয়েছে} ডিফল্টরূপে, আপনি কল করতে পারেন:
convert_pdf(path)
একটি পাঠ্য ফাইল তৈরি করা হবে, মূল সিস্টেমে পিডিএফ থেকে ফাইল সিস্টেমে একটি ভাইবাল।
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
পিডিএফএমনার আমাকে পিডিএফ ফাইলের প্রতিটি পৃষ্ঠায় সম্ভবত একটি লাইন [7 পৃষ্ঠার 1 ...] দিয়েছিল আমি এটি দিয়ে চেষ্টা করেছি।
আমার এখনও অবধি সবচেয়ে ভাল উত্তরটি হল পিডিএফটাইপ, বা এটি সিপিডিএফ ভিত্তিক সি ++ কোড।
পিডিএফটাইপের আউটপুট কেমন লাগে তার জন্য আমার প্রশ্নটি দেখুন ।
অতিরিক্তভাবে পিডিএফটেক্সটস্ট্রিম রয়েছে যা বাণিজ্যিক জাভা গ্রন্থাগার যা পাইথন থেকেও ব্যবহার করা যেতে পারে।
আমি যুক্তিটি pdftohtml
দিয়ে ব্যবহার করেছি, এর সাথে -xml
ফলাফলটি পড়ি subprocess.Popen()
, এটি আপনাকে পিডিএফ এর প্রতিটি টুকরো টুকরো এক্স কোর্ড, ওয়াই কর্ড, প্রস্থ, উচ্চতা এবং ফন্ট দেবে । আমি মনে করি এটিই 'প্রমাণিত' সম্ভবত খুব বেশি ব্যবহার করে কারণ একই ত্রুটি বার্তাগুলি বানান।
আপনার যদি কলামার ডেটা প্রক্রিয়াকরণের দরকার হয় তবে এটি আপনার পিডিএফ ফাইলের জন্য উপযুক্ত একটি অ্যালগরিদম আবিষ্কার করতে হবে বলে এটি কিছুটা জটিল হয়ে যায়। সমস্যাটি হ'ল যে প্রোগ্রামগুলি পিডিএফ ফাইল তৈরি করে সেগুলি অবশ্যই কোনও যৌক্তিক বিন্যাসে পাঠ্য আউট দেয় না। আপনি সরল অ্যালগরিদমগুলি চেষ্টা করে দেখতে পারেন এবং এটি কখনও কখনও কাজ করে তবে সেখানে 'স্ট্রেগলার্স' এবং 'স্ট্রেস', টেক্সটের কিছু অংশ থাকতে পারে যা আপনি ভেবেছিলেন যে ক্রমটি সেগুলি করে না। সুতরাং আপনি সৃজনশীল পেতে হবে।
আমি যে পিডিএফটিতে কাজ করছি তার জন্য একটি নির্ধারণ করতে আমার প্রায় 5 ঘন্টা সময় লেগেছে। তবে এটি এখন বেশ ভাল কাজ করে। শুভকামনা।
আজ সেই সমাধান খুঁজে পেয়েছি। আমার জন্য দুর্দান্ত কাজ করে এমনকি পিএনজি চিত্রগুলিতে পিডিএফ পৃষ্ঠাগুলি রেন্ডারিং। http://www.swftools.org/gfx_tutorial.html