2010-11-27 63 views
2

嗨,我剛開始學習谷歌應用程序引擎,所以我遇到一堆問題......urllib2的,谷歌應用程序引擎,和unicode問題

我目前的困境是這樣的。我有一個數據庫,

class Website(db.Model): 
    web_address = db.StringProperty() 
    company_name = db.StringProperty() 
    content = db.TextProperty() 
    div_section = db.StringProperty() 
    local_links = db.StringProperty() 
    absolute_links = db.BooleanProperty() 
    date_updated = db.DateTimeProperty() 

和我遇到的問題是與內容屬性。

我正在使用db.TextProperty(),因爲我需要存儲具有> 500個字節的網頁的內容。

我遇到的問題是urllib2.readlines()格式爲unicode。在放入TextProperty()時,它將轉換爲ASCII。一些字符大於128,它會引發UnicodeDecodeError。

有沒有簡單的方法來繞過這個?在大多數情況下,我不關心這些字符...

我的錯誤是:

Traceback (most recent call last):
File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/init.py", line 511, in call handler.get(*groups) File "/base/data/home/apps/game-job-finder/1.346504560470727679/main.py", line 61, in get x.content = website_data_joined File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py", line 542, in set value = self.validate(value) File "/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py", line 2407, in validate value = self.data_type(value) File "/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore_types.py", line 1006, in new return super(Text, cls).new(cls, arg, encoding) UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 2124: ordinal not in range(128)

+1

我本來認爲的Unicode轉換成ASCII碼將是「編碼」而不是「解碼」。你確定這不是相反的方式嗎? – 2010-11-27 04:35:47

回答

1

這樣看來,該行返回從readlines不是Unicode字符串,而是字節字符串(即包含潛在非ASCII字符的str的實例)。這些字節是在HTTP響應主體中接收到的原始數據,並將根據所使用的編碼表示不同的字符串。它們需要被「解碼」才能被視爲文本(字節!=字符)。

如果編碼爲UTF-8,此代碼應能正常工作:

f = urllib2.open('http://www.google.com') 
website = Website() 
website.content = db.Text(f.read(), encoding = 'utf-8-sig') # 'sig' deals with BOM if present 

注意實際的編碼從網站到網站不同(有時甚至是逐頁)。使用的編碼應該包含在HTTP響應中的Content-Type頭中(有關如何獲取它,請參閱this question),但如果不是,則可能將其包含在HTML頭部的元標記中(在這種情況下,提取正確的是更棘手):

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 

請注意,有網站沒有指定編碼,或指定錯誤的編碼。

如果你真的不關心任何字符,但ASCII,您可以忽略它們,並用它做:

f = urllib2.open('http://www.google.com') 
website = Website() 
content = unicode(f.read(), errors = 'ignore') # Ignore characters that cause errors 
website.content = db.Text(content) # Don't need to specify an encoding since content is already a unicode string