2017-05-21 1 views
-2

Ce que je veux essentiellement avoir des données PDF sous les en-têtes de ligne ou pour simplifier ce que je dis, je veux créer une base de données à partir du fichier PDF.Chaque PDF se compose de 25 -40 pages selon le nombre d'électeurs.Meilleur langage pour extraire le texte pdf et le tabuler sous les en-têtes de ligne

A page of pdf file I am talking about

Je veux extraire les données des boîtes (ou tout ce que vous leur dites) dans Access/Excel/SQL afin de chaque boîte

nom figure dans la colonne Nom

Relation apparaître sous la colonne de relation et ainsi de suite avec d'autres données

Mais je n'ai aucune idée quel langage de programmation devrais-je apprendre afin de le faire. J'ai essayé de chercher sur PDFminer mais je ne suis pas sûr que ce serait possible pour faire cette tâche ou pas.

Si vous avez des suggestions, S'il vous plaît laissez-moi savoir

+0

Il peut être intéressant de jeter un coup d'œil à la source du fichier pdf; Si cela a été créé par programme (comme c'était presque certainement le cas), il y a de très fortes chances que la source de la page soit présentée de façon régulière et analysable. c'est-à-dire ne pas le traiter comme un .pdf, le traiter comme un fichier texte structuré. –

+0

... ouvrez le fichier .pdf en utilisant un éditeur de texte au lieu d'acrobat. Est-il possible que vous pourriez m'envoyer un échantillon de fichier (un court, préférablement)? –

+0

fait fini de l'envoyer –

Répondre

1

Beaucoup plus déblayage au sujet que je pensais, mais cela fonctionne:

import csv # spreadsheet output 
import re  # pattern matching 
import sys # command-line arguments 
import zlib # decompression 

# find deflated sections 
PARENT = b"FlateDecode" 
PARENTLEN = len(PARENT) 
START = b"stream\r\n" 
STARTLEN = len(START) 
END = b"\r\nendstream" 
ENDLEN = len(END) 

# find output text in PostScript Tj and TJ fields 
PS_TEXT = re.compile(r"(?<!\\)\((.*?)(?<!\\)\)") 

# return desired per-person records 
RECORD = re.compile(r"Name : (.*?)Relation : (.*?)Address : (.*?)Age : (\d+)\s+Sex : (\w?)\s+(\d+)", re.DOTALL) 

def get_streams(byte_data): 
    streams = [] 
    start_at = 0 
    while True: 
     # find block containing compressed data 
     p = byte_data.find(PARENT, start_at) 
     if p == -1: 
      # no more streams 
      break 
     # find start of data 
     s = byte_data.find(START, p + PARENTLEN) 
     if s == -1: 
      raise ValueError("Found parent at {} bytes with no start".format(p)) 
     # find end of data 
     e = byte_data.find(END, s + STARTLEN) 
     if e == -1: 
      raise ValueError("Found start at {} bytes but no end".format(s)) 
     # unpack compressed data 
     block = byte_data[s + STARTLEN:e] 
     unc = zlib.decompress(block) 
     streams.append(unc) 
     start_at = e + ENDLEN 
    return streams 

def depostscript(text): 
    out = [] 
    for line in text.splitlines(): 
     if line.endswith(" Tj"): 
      # new output line 
      s = "".join(PS_TEXT.findall(line)) 
      out.append(s) 
     elif line.endswith(" TJ"): 
      # continued output line 
      s = "".join(PS_TEXT.findall(line)) 
      out[-1] += s 
    return "\n".join(out) 

def main(in_pdf, out_csv): 
    # load .pdf file into memory 
    with open(in_pdf, "rb") as f: 
     pdf = f.read() 

    # get content of all compressed streams 
    # NB: sample file results in 32 streams 
    streams = get_streams(pdf)  

    # we only want the streams which contain text data 
    # NB: sample file results in 22 text streams 
    text_streams = [] 
    for stream in streams: 
     try: 
      text = stream.decode() 
      text_streams.append(text) 
     except UnicodeDecodeError: 
      pass 

    # of the remaining blocks, we only want those containing the text '(Relation : ' 
    # NB: sample file results in 4 streams 
    text_streams = [t for t in text_streams if '(Relation : ' in t] 

    # consolidate target text 
    # NB: sample file results in 886 lines of text 
    text = "\n".join(depostscript(ts) for ts in text_streams) 

    # pull desired data from text 
    records = [] 
    for name,relation,address,age,sex,num in RECORD.findall(text): 
     name = name.strip() 
     relation = relation.strip() 
     t = address.strip().splitlines() 
     code = t[-1] 
     address = " ".join(t[:-1]) 
     age = int(age) 
     sex = sex.strip() 
     num = int(num) 
     records.append((num, code, name, relation, address, age, sex)) 

    # save results as csv 
    with open(out_csv, "w", newline='') as outf: 
     wr = csv.writer(outf) 
     wr.writerows(records) 

if __name__ == "__main__": 
    if len(sys.argv) < 3: 
     print("Usage: python {} input.pdf output.csv".format(__name__)) 
    else: 
     main(sys.argv[1], sys.argv[2]) 

Effectué à la ligne de commande comme

python myscript.py voters.pdf voters.csv 

il produit une feuille de calcul .csv comme

enter image description here

0

Je l'ai fait un travail collégial que je devais lire pdf et extraire des données de leur part. J'ai utilisé PyPDF2 à l'époque. J'ai eu beaucoup de problèmes avec l'encodage de caractères lors de l'extraction des données et les gens qui utilisaient Java (je ne peux pas dire quelle bibliothèque ils utilisaient) n'avaient pas ce genre de problème.

Mon conseil est que vous essayiez d'utiliser Java ou une autre 'pypdf'library autre que PytoPDF2.

Quand il s'agit de traiter des données 'chaîne', je pense que Python est la meilleure option.

Juste une chose que je pense que vous devriez considérer. Si vous avez un manque d'expérience en programmation Python est un bon langage pour commencer, Java est un peu plus effrayant.

0

PyMuPDF le rend assez facile. J'ai pris une page similaire à celle que vous voulez traiter à http://ceodelhi.gov.in/WriteReadData/AssemblyConstituency4/AC13/AC0130022.pdf et appliqué cette bibliothèque de la manière suivante pour obtenir du HTML qui est facilement analysé avec, disons, BeautifulSoup ou lxml.

>>> import fitz 
>>> doc = fitz.open('AC0130022.pdf') 
>>> page = doc.loadPage(3) 
>>> text = page.getText(output='html') 
>>> len(text) 
52807 
>>> open('page3.html','w').write(text) 
52807 

Il y a un tutoriel pour PyMuPDF à https://pythonhosted.org/PyMuPDF/tutorial.html.