urllib2,Google App Engine和unicode问题

时间:2010-11-27 04:26:43

标签: python google-app-engine urllib2

嘿伙计们,我只是在学习谷歌应用引擎,所以我遇到了一堆问题......

我目前的困境是这样的。我有一个数据库,

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。

有没有一种简单的方法可以绕过这个?在大多数情况下,我不关心那些角色......

我的错误是:

  

追踪(最近的呼叫最后):
  文件   “/base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/init.py”   第511行,在通话中       handler.get(* groups)文件“/base/data/home/apps/game-job-finder/1.346504560470727679/main.py”,第61行,在get中       x.content = website_data_joined文件   “/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py”   第542行,设置       value = self.validate(value)文件   “/base/python_runtime/python_lib/versions/1/google/appengine/ext/db/init.py”   第2407行,在验证中       value = self.data_type(value)文件   “/base/python_runtime/python_lib/versions/1/google/appengine/api/datastore_types.py”   第1006行, new       return super(Text,cls)。 new (cls,arg,encoding)   UnicodeDecodeError:'ascii'编解码器   无法将字节0xc2解码到位   2124:序数不在范围内(128)

1 个答案:

答案 0 :(得分: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