2016-04-27 8 views
3

Ich möchte in der Lage sein PDF-Dateien in CSV-Dateien zu konvertieren und haben einige nützliche Skripte gefunden, aber, zu Python ist neu, habe ich eine Frage:Python PDFMIner - PDF to CSV

Wo Sie den Dateipfad der nicht angeben PDF und die CSV, auf die Sie drucken möchten?

Ich verwende Python 2.7.11 und PDFMiner 20140328.

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) 
    interpreter = PDFPageInterpreter(rsrcmgr, device) 


    for page in PDFPage.get_pages(fp): 
    interpreter.process_page(page) 
    data = retstr.getvalue() 

    print data 

if __name__ == '__main__': 
pdfparser(sys.argv[1]) 
+0

1. Eingabe auf der Befehlszeile ist: 'pdfparser (sys.argv [1])'. 2. Dieser Code wird nicht in eine Datei gedruckt, er druckt * nur *: 'Druckdaten'. Ich denke, Sie wollen etwas wie 'python yourScriptName.py input.pdf> output.csv'. Aber zuerst müssen Sie einige Einrückungsfehler korrigieren oder sicherstellen, dass Sie die Quelle korrekt kopiert haben. – usr2564301

Antwort

5

hier etwas modifizierte Code this SO durch tgray schriftliche Antwort:

def pdf_to_csv(filename, separator, threshold): 
    from cStringIO import StringIO 
    from pdfminer.converter import LTChar, TextConverter 
    from pdfminer.layout import LAParams 
    from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter 
    from pdfminer.pdfpage import PDFPage 

    class CsvConverter(TextConverter): 
     def __init__(self, *args, **kwargs): 
      TextConverter.__init__(self, *args, **kwargs) 
      self.separator = separator 
      self.threshold = threshold 

     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.line_creator(line) 
       self.outfp.write(self.line_creator(line)) 
       self.outfp.write("\n") 

     def line_creator(self, line): 
      keys = sorted(line.keys()) 
      # calculate the average distange between each character on this row 
      average_distance = sum([keys[i] - keys[i - 1] for i in range(1, len(keys))])/len(keys) 
      # append the first character to the result 
      result = [line[keys[0]]] 
      for i in range(1, len(keys)): 
       # if the distance between this character and the last character is greater than the average*threshold 
       if (keys[i] - keys[i - 1]) > average_distance * self.threshold: 
        # append the separator into that position 
        result.append(self.separator) 
       # append the character 
       result.append(line[keys[i]]) 
      printable_line = ''.join(result) 
      return printable_line 

    # ... 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) 

    fp = open(filename, 'rb') 

    interpreter = PDFPageInterpreter(rsrc, device) 
    for i, page in enumerate(PDFPage.get_pages(fp)): 
     outfp.write("START PAGE %d\n" % i) 
     if page is not None: 
      print 'none' 
      interpreter.process_page(page) 
     outfp.write("END PAGE %d\n" % i) 

    device.close() 
    fp.close() 

    return outfp.getvalue() 


if __name__ == '__main__': 
    # the separator to use with the CSV 
    separator = ';' 
    # the distance multiplier after which a character is considered part of a new word/column/block. Usually 1.5 works quite well 
    threshold = 1.5 
    print pdf_to_csv('myLovelyFile.pdf', separator, threshold) 

Der Hauptunterschied zwischen der Antwort in Der Link und dieser ist die line_creator-Methode, die versucht, eine Struktur aus dem PDF zu extrahieren.

Sollte mit PDFminer arbeiten 20140328.