2017-05-21 14 views
-2

基本的には行ヘッダーの下にPDFデータがありますか、私が言っていることを単純化するために、PDFファイルからデータベースを作成したいと思います。有権者数に応じて40ページ。アクセス/エクセル/ SQLに私はボックスからデータを抽出したい(またはあなたがそれらを言って何でも)pdfテキストを抽出し、それを行ヘッダーの下に集計する最適な言語

A page of pdf file I am talking about

各ボックスから

名前は、名前欄の下に

関係を表示されるように他のデータとの関連列などに表示されます

しかし、これを行うためにどのプログラミング言語を学ばなければならないのですか?私はPDFminerについて検索しましたが、それが可能かどうかはわかりませんこの作業を行うかどうか。

ご提案があれば、私は、私はPDFファイルを読み込み、そこからいくつかのデータを抽出するために必要な大学の仕事をやった

+0

pdfファイルのソースを参照してください。これがプログラムで作成されていれば(ほぼ確実だった)、ページソースが定期的に解析可能な方法でレイアウトされている可能性が非常に高いです。すなわち、それを.pdfとして扱わないで、それを構造化テキストファイルとして扱います。 –

+0

... acrobatの代わりにテキストエディタを使用して.pdfファイルを開きます。サンプルファイルを私にメールで送ることは可能でしょうか(短いもの、好きなもの)? –

+0

完了しました –

答えて

1

私は思ったが、それが動作よりももっとたくさんについていじくる:

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]) 

python myscript.py voters.pdf voters.csv 

のように、コマンドラインで実行すると、それは

enter image description hereのようなの.csvスプレッドシートを作成します

0

を教えてください。私はその時点でPyPDF2を使いました。データを抽出する際に文字エンコーディングに問題があり、Javaを使用していた人が(このライブラリを使用しているとは言えません)この種の問題はありませんでした。

私はPytoPDF2以外のJavaや他の 'pypdf'ライブラリを試してみることを勧めます。

「文字列」データの処理については、Pythonが最適な選択肢だと思います。

私はあなたが考慮すべきもう一つのことを考えます。あなたがプログラミング経験が不足している場合、Pythonは素晴らしい言語です。Javaは少し怖いです。

0

PyMuPDFかなり簡単です。私はhttp://ceodelhi.gov.in/WriteReadData/AssemblyConstituency4/AC13/AC0130022.pdfで処理したいものと同様のページをとり、次のようにこのライブラリを適用して、BeautifulSoupやlxmlと簡単に解析できるHTMLを取得しました。

>>> 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 

https://pythonhosted.org/PyMuPDF/tutorial.htmlPyMuPDFのためのチュートリアルがあります。

関連する問題