2013-03-17 69 views
1

我在每個頁面包含一個地址的PDF文件。該地址格式爲:如何讓pypdf逐行閱讀頁面內容?

Location Name 

Street Address 

City, State Zip 

例如:

The Gift Store 

620 Broadway Street 

Van Buren, AR 72956 

每一個地址僅在這種格式,並各自爲PDF的不同頁面上。

我需要提取的地址信息,並存儲在Excel/CSV文件的結果。我需要爲每個信息領域分開輸入。我的Excel表格需要具有位置名稱,街道地址,城市,州,郵編全部在不同的列。我在Python中使用pyPdf。

我用下面的代碼來做到這一點,但我的代碼是不是考慮換行;而是將單個頁面的整個數據作爲連續字符串提供。

import pyPdf 
def getPDFConten(path): 
    content = "" 
    num_pages = 10 
    p = file(path, "rb") 
    pdf = pyPdf.PdfFileReader(p) 
    for i in range(9, num_pages): 
     x = pdf.getPage(i).extractText()+'\n' 
     content += x 

    content = " ".join(content.replace(u"\xa0", " ").strip().split())  
    return content 

con = getPDFContent("document.pdf") 
print con 

或我它給「的禮品店620百老匯街範布倫,AR 72956」上面的例子。

如果我可以一行一行地讀取輸入,那麼我可以很容易地從前兩行讀取位置名稱和Stree地址,使用子字符串從第三行讀取其餘行。

我試圖用[這裏(pyPdf ignores newlines in PDF file)中列出的解決方案,但它並沒有爲我工作。我也嘗試使用pdfminer:它可以逐行提取信息,但它首先將pdf轉換爲文本文件,而我不想這樣做。我只想使用pyPdf。任何人都可以提出我錯在哪裏或我錯過了什麼?這可能使用pyPdf嗎?

+0

你能提供一個樣本PDF?如果你引用的解決方案沒有幫助,你可能會有非常特殊的結構。 – mkl 2013-03-17 16:47:19

回答

3

你可以嘗試使用subprocess調用pdftotext(可能與-layout選項)從poppler工具。對我來說,它比使用pypdf好得多。

例如我用下面的代碼從一個PDF文件中提取CAS編號:

import subprocess 
import re 

def findCAS(pdf, page=None): 
    '''Find all CAS numbers on the numbered page of a file. 

    Arguments: 
    pdf -- Name of the PDF file to search 
    page -- number of the page to search. if None, search all pages. 
    ''' 
    if page == None: 
     args = ['pdftotext', '-layout', '-q', pdf, '-'] 
    else: 
     args = ['pdftotext', '-f', str(page), '-l', str(page), '-layout', 
       '-q', pdf, '-'] 
    txt = subprocess.check_output(args) 
    candidates = re.findall('\d{2,6}-\d{2}-\d{1}', txt) 
    checked = [x.lstrip('0') for x in candidates if checkCAS(x)] 
    return list(set(checked)) 

def checkCAS(cas): 
    '''Check if a string is a valid CAS number. 

    Arguments: 
    cas -- string to check 
    ''' 
    nums = cas[::-1].replace('-', '') # all digits in reverse order 
    checksum = int(nums[0]) # first digit is the checksum 
    som = 0 
    # Checksum method from: http://nl.wikipedia.org/wiki/CAS-nummer 
    for n, d in enumerate(nums[1:]): 
     som += (n+1)*int(d) 
    return som % 10 == checksum