2009年3月30日 星期一

PyPdf 讀取中文Pdf亂碼問題

最近找論文資料常常會下載一堆相關題目的pdf檔然後慢慢消化,不過這樣實在是很浪費時間,所以週末就想說寫一隻程式搜尋資料夾中所有pdf,然後給它關鍵詞,最後能夠顯示這些關鍵詞在哪幾篇pdf的第幾頁中,如此一來就省事多了。

python的好處就是擴充套件多如過江之鯽,當然光pdf就好多個,這裡挑選的是PyPdf.

安裝完成之後先以取出內容文字為主寫出一段程式測試,測試pdf為中文big5編碼,但除了標題encode("big5")能夠正常顯示中文外,內容卻是一片亂碼,於是把每段文字拆解成char再使用hex code列印出來...

0xb8 0xea ... 這不是big5的"資"嗎?表示編碼是正確的阿!為何print就是有錯誤?

於是我使用一個範例字串 zh = "\xb8\xea" ,print出來是"資"沒錯,但 u"\xb8\xea" 加上unicode就會和上面呈現一模一樣的亂碼。原來PyPdf中PageObject extractText()會將所有內容編碼成unicode,所以我們要把unicode反解回來 str.encode('latin-1') ,嗯正常了^^。

#!/usr/local/bin/python
# -*- coding: utf-8 -*-

from pyPdf import PdfFileReader

input = PdfFileReader(file("infosafe.pdf", "rb"))

# Show title from this pdf.
print input.getDocumentInfo().title.encode("big5")

# Total pages.
pages = input.getNumPages()

# Loop to print content.
for i in range(0, pages):
    pageObj = input.getPage(i)
    str = pageObj.extractText()
    
    # The extracted text has been set to unicode, therefore, we should transfer it's format to the normal 'latin-1'.
    print str.encode('latin-1')
    
    """
    # Print hex code.
    for j in range(0, len(str)):
        print hex(ord(str[j]))
    
    break
    """
"""
# This is an example.
zh = u"\xb8\xea".encode('latin-1')
print type(zh)
print zh
"""

3 則留言:

  1. 您好

    我透過您這篇文章進而瞭解到python這個程式語言
    (第一次看到 也多了個新語言)

    可是好像跟其他語言不太一樣(VB C++)

    他執行似乎不是跑出一個程式OR視窗執行黨

    因為我嘗試用您上面的範例把PDF複製到WORD會產生亂碼的PDF黨轉成中文


    不過似乎我對這之程式語言不太了解。。。。

    回覆刪除
  2. 聽你的敘述你沒有了解python的真正定義...請去找書看(O'Reilly Learning Python 3rd Edition)

    這範例似乎只對"某些"pdf有效...我也是後來拿很多版本來測試, 尤其是加密的部分還是有問題, 不過用Java的套件解的開。

    Python 不是新語言歐... 1989年就開始發展了, 和Java是同期, 之所以2005年以後開始紅是因為Google, Youtube大部分的東西都使用python開發, 總之...將來你就知道了。

    回覆刪除
  3. I tried with one pdf and it was exactly the case you met.

    The pypdf naively encodes what it extracts with 'latin-1'

    回覆刪除