2012-10-02 36 views
0

我需要從pdf流中提取一些信息。
這是很簡單的提取相關的文字,因爲它是這樣的:
通過正則表達式將頁面區分爲pdf流

BT /Fo0 7.20 Tf 67.81 569.38 Td 0.000 Tc (TOTAL AMOUNT) Tj ET 

我可以考慮固定y位置,而x位置是由於giustification變量。 但我的問題是承認一個頁面的開始及其結束。

+0

哪一個是相關的文字部分? – Gabber

+0

在此示例中,爲「總金額」。但是在一些頁面中,它缺失了,我不僅需要在它出現時將其提取出來,還要列出它不存在的頁面。 – AgostinoX

+0

如果你發佈了一個(真的)*代表你的東西的樣本PDF樣本,這將有所幫助。這些PDF文件是否有多個頁面? –

回答

2

您不應該確定您在「信息提取器」中遇到的所有PDF都表現得如此之好。或者你可以,因爲你知道他們是?

否則,它可以很好地發生,你會遇到PDF的代碼如下所示:

BT 
    /Fo0 7.20 Tf 
    67.81 569.38 Td 
    0.000 Tc 
    (TO)12(T)13(AL A)11(M)14(OUNT) TJ 
ET 

也就是說,...

  • ...使用TJ代替Tj,以允許個性化的字形定位,
  • ...有更多的lineline,
  • ...也許更多modifikations。

爲了可靠地獲取頁面的文本內容,你必須解析PDF的結構,簡稱:

  1. 找到/Type /Page所有對象;
  2. 轉到這些頁面對象的每一個,並檢索其各自的/Contents所在的信息;
    • /Contents可指向單流或
    • /Contents可指向流的陣列;
  3. 轉到此內容對象並提取其流(s)。

在實際應用中,第一上述步驟可以變成一個有點複雜:

  • 發現,去拖車的trailer <<...>>部分
  • 找到有關文檔的/Root的信息對象
  • 轉到根對象
  • /Root對象中提取有關/Pages的信息
  • 轉到/Pages對象(這是一箇中間媒介頁面樹節點與孩子和父母;
  • 查找此頁樹形節點的所有下降,從檢查/Kids對象
  • 轉到/Kids列出的各個對象;
    • 它可能是/Type /Pages(在這種情況下,它是另一個頁面樹節點,不是樹,你必須進一步跟蹤下來的樹);
    • 它可能是/Type Page(在這種情況下,你到達了一個頁面樹這意味着你真的抵達了一頁)。

在這一點上,我應該注意,第一頁,你發現以下這段旅程是1頁接下來是第2頁,等等。注意,沒有頁面有說:「我的任何元數據頁碼N「 - 這完全取決於你解析從根對象開始的頁面樹的順序。

現在你真的找到了內容流,你正面臨着兩個問題:

  1. 內容流你正在尋找可能不會以明文形式在所有(如您的代碼顯示)。內容流經常被一種允許的壓縮方案壓縮,並且在解析文本內容之前,您必須展開它們。

    要查看一個數據流是否被壓縮,請留意相應的*解碼關鍵字(非常頻繁地出現爲/Filter /FlateDecode)。

  2. 一旦您成功解壓縮頁面的內容流,您可能會遇到完全不直觀的字符代碼來描述您的文本。它可能根本不是您想象中的並且在您的示例代碼中顯示的同類型的表現良好的ASCII。

    你必須查找字體(甚至像CID這樣的多字節字體),它們的編碼,CMaps和什麼不是。

    除非,正如我在最初的一句質疑,你知道這不是你的具體使用情況下發生的事情......

+1

偉大的答案,它提供了一個完整的PDF文件的結構。我沒有試圖以可靠的方式解釋pdf。目的是實現一個人類輔助數據提取器,更像是一個OCR。這些文件是「表格」(不是pdf格式),帶有箱子限制的佈局。所以理想情況下,我可以說每個頁面上都有一個包含(x0; y0-x1; y1)的框(示例的總數)。我需要提取這方面的文字。很明顯,我不能依賴x,y開頭的文本,但需要更復雜的東西,並考慮到您所做的所有考慮。用於解壓我使用iText的流。 – AgostinoX