urllib2, Google App Engine и вопрос о юникоде - PullRequest
2 голосов
/ 27 ноября 2010

Эй, ребята, я только изучаю движок приложений Google, поэтому у меня куча проблем ...

Мое нынешнее затруднение заключается в следующем.У меня есть база данных,

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 () форматирует как юникод.При помещении в TextProperty () он конвертируется в ASCII.некоторые из символов> 128, и он выдает UnicodeDecodeError.

Есть ли простой способ обойти это?По большей части меня не волнуют эти символы ...

моя ошибка:

Трассировка (последний вызов был последним):
File "/ base/python_runtime/python_lib/versions/1/google/appengine/ext/webapp/init.py ", строка 511, в call handler.get (* groups) File" / base/data/home/apps/game-job-finder/1.346504560470727679/main.py ", строка 61, в файле get x.content = website_data_joined" / base / python_runtime / python_lib / версии / 1 / google / appengine / ext / db/init.py ", строка 542, в set value = self.validate (value) File" / base / python_runtime / python_lib / version / 1 / google / appengine / ext /db / init .py ", строка 2407, в значении validate = 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 Ответ

1 голос
/ 28 ноября 2010

Может показаться, что строки, возвращаемые из readlines, не являются строками Unicode, а являются байтовыми строками (т.е. экземплярами str, содержащими потенциально не-ASCII-символы).Эти байты являются необработанными данными, полученными в теле ответа 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

Обратите внимание, что фактическая кодировка варьируется от сайта к сайту (иногда даже от страницы к странице).Используемая кодировка должна быть включена в заголовок Content-Type в HTTP-ответе (см. этот вопрос , чтобы узнать, как ее получить), но если это не так, она может быть включена в метатег в заголовке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
...