Проблема с кодированным декодированием.Python.Джанго.BeautifulSoup - PullRequest
0 голосов
/ 14 августа 2010

В этом коде:

   soup=BeautifulSoup(program.Description.encode('utf-8'))
   name=soup.find('div',{'class':'head'})
   print name.string.decode('utf-8')

ошибка происходит, когда я пытаюсь распечатать или сохранить в базе данных.

Добрый день, что я делаю:

print name.string.encode('utf-8')

или просто

 print name.string


Traceback (most recent call last):
  File "./manage.py", line 16, in <module>
    execute_manager(settings)
  File "/usr/local/cluster/dynamic/virtualenv/lib/python2.5/site-packages/django/core/management/__init__.py", line 362, in execute_manager
    utility.execute()
  File "/usr/local/cluster/dynamic/virtualenv/lib/python2.5/site-packages/django/core/management/__init__.py", line 303, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "/usr/local/cluster/dynamic/virtualenv/lib/python2.5/site-packages/django/core/management/base.py", line 195, in run_from_argv
    self.execute(*args, **options.__dict__)
  File "/usr/local/cluster/dynamic/virtualenv/lib/python2.5/site-packages/django/core/management/base.py", line 222, in execute
    output = self.handle(*args, **options)
  File "/usr/local/cluster/dynamic/website/video/remmedia/management/commands/remmedia.py", line 50, in handle
    self.FirstTimeLoad()
  File "/usr/local/cluster/dynamic/website/video/remmedia/management/commands/remmedia.py", line 115, in FirstTimeLoad
    print name.string.decode('utf-8')
  File "/usr/lib/python2.5/encodings/utf_8.py", line 16, in decode
    return codecs.utf_8_decode(input, errors, True)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-5: ordinal not in range(128)

Это repr (name.string)

u 'u1212 \ u0443 \ u0443 \ u043a \ u043e \ u0442 27 \ u0434 \ u043a \ u0430 \ u0430 \ u0440 \ u044f'

Ответы [ 4 ]

5 голосов
/ 14 августа 2010

Я не знаю, что вы пытаетесь сделать с name.string.decode('utf-8').Как красноречиво указывает документация BeautifulSoup , «BeautifulSoup дает вам Unicode, черт побери».Так что name.string уже декодировано - оно в юникоде.Вы можете кодировать его обратно в utf-8, если хотите, но вы не можете его декодировать дальше.

4 голосов
/ 14 августа 2010

Вы можете попробовать:

print name.string.encode('ascii', 'replace')

Вывод должен быть принят независимо от того, какая кодировка sys.stdout (включая None).

Фактически, файлоподобный объект, на который вы печатаете, может не поддерживать UTF-8. Вот пример: если у вас явно мягкая программа

# -*- coding: utf-8 -*-
print u"hérisson"

тогда запуск его в терминале, который может печатать символы с акцентом, работает нормально:

lebigot@weinberg /tmp % python2.5 test.py 
hérisson

, но печать на стандартный вывод, подключенный к каналу Unix, не выполняется:

lebigot@weinberg /tmp % python2.5 test.py | cat
  Traceback (most recent call last):
  File "test.py", line 3, in <module>
print u"hérisson"
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in position 1: ordinal not in range(128)

потому что sys.stdout имеет кодировку None, в данном случае: Python считает, что программа, которая читает через канал, должна получить ASCII, и печать завершается неудачно, потому что ASCII не может представлять слово, которое мы хотим напечатать. Решение, подобное приведенному выше, решает проблему.

Примечание: Вы можете проверить кодировку вашего стандартного вывода с помощью:

print sys.stdout.encoding

Это может помочь вам отладить проблемы с кодировкой.

0 голосов
/ 14 августа 2010

попробуй

text = text.decode("utf-8", "replace")
0 голосов
/ 14 августа 2010

Редактировать : name.string исходит от BeautifulSoup, поэтому, по-видимому, это уже строка Юникода.

Однако в вашем сообщении об ошибке упоминается «ascii»:

UnicodeEncodeError: 'ascii' codec can't encode characters in position 2-5:
ordinal not in range(128)

В соответствии со страницей PrintFails Python , если Python не знает или не может определить, какую кодировку ожидает ваше устройство вывода, оно устанавливает sys.stdout.encoding для None и print пытается закодировать свои аргументы с кодек "ASCII".

Я считаю, что это является причиной вашей проблемы. Вы можете подтвердить это, увидев если print sys.stdout.encoding печатает None.

Согласно той же странице, на которую вы ссылаетесь выше, вы можете обойти проблему, явно говорит Python, какую кодировку использовать. Вы делаете это обертывание sys.stdout в экземпляре StreamWriter:

Например, вы можете попробовать добавить

import sys
import locale
sys.stdout = codecs.getwriter(locale.getpreferredencoding())(sys.stdout)

к вашему сценарию перед оператором print. Возможно, вам придется изменить locale.getpreferredencoding() to и явное кодирование (например, 'utf-8', «cp1252» и т. д.). Правильная кодировка зависит от вашего устройства вывода. Он должен быть установлен в любую кодировку, ожидаемую вашим устройством вывода. Если вы выводите на терминал, терминал может иметь настройку меню, чтобы позволить пользователь должен указать, какой тип кодирования должен ожидать терминал.

Оригинальный ответ: Попробуйте:

 print name.string

или

 print name.string.encode('utf-8')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...