2010-09-10 45 views
2

我使用Python Google App Engine來簡單獲取html頁面並顯示它。我的目標是能夠以任何語言獲取任何頁面。現在,我有編碼的一個問題:Urllib2 - 獲取並顯示任何語言頁面,編碼問題

Simple

result = urllib2.urlopen(url).read() 

留下的文物代替特殊字母和

urllib2.urlopen(url).read().decode('utf8') 

拋出錯誤:

'utf8' codec can't decode bytes in position 3544-3546: invalid data

那麼該如何解決呢?有沒有任何lib將檢查什麼編碼 頁和轉換,所以它會是可讀?

回答

2

So how to solve it?

那麼,你必須得到原始字節。一旦你下載了原始字節,你實際上可以打印它們,並實際上看看它們,看看問題實際上是什麼。

Is there any lib that would check what encoding page is and convert so it would be readable?

頁面本身說明它的編碼是什麼。你可以認爲它是UTF-8,但事實並非如此。

如果頁面是XML或XHTML,則<?xml開頭包含編碼。

該頁面有一個內容類型標題Content-Type: text/plain; charset="UTF-8",它具有編碼。

正確解碼頁面非常容易。

第1步。不要認爲該頁面是UTF-8。

第2步。獲取內容,閱讀標題。

第3步。使用標題中指定的編碼,而不是假定的UTF-8編碼。

0

這並不直接回答你的問題,但我認爲在urllib2.urlopen Python 2.5(以及App Engine中的)是一團糟。對於初學者來說,除200之外的所有2xx狀態碼本身都會引發異常(http://bugs.python.org/issue1177)。

我發現使用GAE的urlfetch獲取頁面要容易得多。

+0

謝謝你的建議。 – Jask 2010-09-10 16:17:42

1

是的,它看起來像urllib2只是忽略了Content-Type屬性。

由於現在大多數網頁都是UTF-8編碼,所以我只是使用快速和髒的方法來處理ISO-8859-1頁面。很明顯,如果你想抓取不是UTF-8編碼的中文頁面,這是行不通的。

這不是很漂亮,但它爲我工作:

def read_url(url): 
    reader_req = urllib2.Request(url) 
    reader_resp = urllib2.urlopen(reader_req) 
    reader_resp_content = reader_resp.read() 
    reader_resp.close() 

    try: 
     return reader_resp_content.decode('utf-8') 
    except: 
     pass 

    try: 
     iso_string = reader_resp_content.decode('iso-8859-1') 
     print 'UTF-8 decoding failed, but ISO-8859-1 decoding succeeded' 
     return iso_string 
    except Exception, e: 
     print e 
     raise 

編輯:因爲我已經意識到,這太黑客和使用要求庫,這似乎處理的編碼只要找到開始:http://docs.python-requests.org/

r = requests.get('https://api.github.com/user', auth=('user', 'pass')) 
t = r.text