Мой код просто очищает веб-страницу, а затем преобразует ее в Unicode.
html = urllib.urlopen(link).read()
html.encode("utf8","ignore")
self.response.out.write(html)
Но я получаю UnicodeDecodeError
:
Traceback (most recent call last):
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/google/appengine/ext/webapp/__init__.py", line 507, in __call__
handler.get(*groups)
File "/Users/greg/clounce/main.py", line 55, in get
html.encode("utf8","ignore")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 2818: ordinal not in range(128)
Я предполагаю, что это означает, что HTML содержит какую-то неправильно сформированную попытку Unicode где-то. Могу ли я просто отбросить те байты кода, которые вызывают проблему, вместо того, чтобы получить ошибку?
c2
байт, или вы, вероятно, получите ошибку декодирования: hexutf8.com/?q=C2A0Ответы:
2018 Обновление:
По состоянию на февраль 2018 года использование таких сжатий
gzip
стало довольно популярным (около 73% всех веб-сайтов используют его, включая такие крупные сайты, как Google, YouTube, Yahoo, Wikipedia, Reddit, Stack Overflow и Stack Exchange Network).Если вы выполните простое декодирование, как в исходном ответе с gzipped ответом, вы получите сообщение об ошибке, похожее на это:
Чтобы декодировать ответ gzpipped, вам необходимо добавить следующие модули (в Python 3):
Примечание: в Python 2 вы бы использовали
StringIO
вместоio
Затем вы можете разобрать содержимое следующим образом:
Этот код читает ответ и помещает байты в буфер. Затем
gzip
модуль читает буфер, используяGZipFile
функцию. После этого файл gzipped можно снова прочитать в байты и в конце декодировать в нормально читаемый текст.Оригинальный ответ от 2010 года:
Можем ли мы получить фактическое значение, используемое для
link
?Кроме того, мы обычно сталкиваемся с этой проблемой, когда пытаемся
.encode()
использовать уже закодированную строку байтов. Таким образом, вы можете попытаться декодировать его сначала, как вНапример:
Сбой с
Пока:
Успешно без ошибок. Обратите внимание, что «windows-1252» - это то, что я использовал в качестве примера . Я получил это от Chardet, и у него было 0,5 уверенности, что это правильно! (ну, как и в случае со строкой длиной в 1 символ, что вы ожидаете) Вы должны изменить это на кодирование строки байтов, возвращаемой
.urlopen().read()
на то, что относится к содержимому, которое вы получили.Другая проблема, которую я вижу, заключается в том, что
.encode()
метод string возвращает измененную строку и не изменяет источник на месте. Так что это бесполезно иметь,self.response.out.write(html)
поскольку html не является закодированной строкой из html.encode (если это то, к чему вы изначально стремились).Как предложил Игнасио, проверьте исходную веб-страницу на предмет фактической кодировки возвращаемой строки из
read()
. Это либо в одном из мета-тегов, либо в заголовке ContentType в ответе. Используйте это тогда как параметр для.decode()
.Однако обратите внимание, что не следует предполагать, что другие разработчики несут достаточную ответственность, чтобы убедиться, что объявления заголовка и / или набора метасимволов соответствуют фактическому содержанию. (Что такое PITA, да, я должен знать, я был одним из них раньше).
источник
encoded_str = decoded_str.encode("utf8")
raise IOError, 'Not a gzipped file'
. В чем я виноват?Декодируйте полученную строку, используя либо кодировку в соответствующем
meta
теге в ответе, либо вContent-Type
заголовке, затем кодируйте.Метод
encode(encoding, errors)
принимает пользовательские обработчики ошибок. Кроме тогоignore
, значения по умолчанию :См. Https://docs.python.org/3/library/stdtypes.html#str.encode
источник
Как продолжение ответа Игнасио Васкеса-Абрамса
Иногда желательно убрать акценты с символов и распечатать базовую форму. Это может быть достигнуто с
Вы также можете захотеть перевести другие символы (например, знаки пунктуации) в их ближайшие эквиваленты, например, символ юникода RIGHT SINGLE QUOTATION MARK не конвертируется в ascii APOSTROPHE при кодировании.
Хотя есть более эффективные способы сделать это. См. Этот вопрос для получения более подробной информации. Где находится «лучшая ASCII для этого Unicode» Python?
источник
Используйте unidecode - он даже мгновенно преобразует странные символы в ascii и даже преобразует китайский язык в фонетический ascii.
затем:
источник
Я использую эту вспомогательную функцию во всех моих проектах. Если он не может конвертировать юникод, он игнорирует его. Это связано с библиотекой Django, но с небольшим исследованием вы можете обойти это.
Я больше не получаю никаких ошибок Unicode после использования этого.
источник
Для сломанных консолей, таких как
cmd.exe
и вывод HTML, вы всегда можете использовать:Это сохранит все символы, отличные от ascii, и сделает их печатными как в чистом ASCII, так и в HTML.
ВНИМАНИЕ : Если вы используете это в рабочем коде, чтобы избежать ошибок, то, скорее всего, в вашем коде что-то не так . Единственным допустимым вариантом использования для этого является печать на консоли, не поддерживающей Юникод, или простое преобразование в объекты HTML в контексте HTML.
И, наконец, если вы работаете в Windows и используете cmd.exe, вы можете ввести
chcp 65001
вывод utf-8 (работает со шрифтом Lucida Console). Возможно, вам придется добавитьmyUnicodeString.encode('utf8')
.источник
Вы написали "" "Я предполагаю, что это означает, что HTML содержит какую-то неправильно сформированную попытку где-то использовать юникод." ""
Не предполагается, что HTML-код будет содержать какую-либо «попытку в кодировке Unicode», правильную или нет. Он должен обязательно содержать символы Unicode, закодированные в некоторой кодировке, которая обычно предоставляется заранее ... ищите "charset".
Вы, кажется, предполагаете, что кодировка UTF-8 ... на каких основаниях? Байт "\ xA0", который отображается в вашем сообщении об ошибке, указывает, что у вас может быть однобайтовая кодировка, например cp1252.
Если вы не можете понять смысл объявления в начале HTML-кода, попробуйте использовать chardet, чтобы узнать, какова вероятная кодировка.
Почему вы пометили свой вопрос "регулярное выражение"?
Обновите после того, как вы заменили весь свой вопрос без вопроса:
источник
Если у вас есть строка
line
, вы можете использовать.encode([encoding], [errors='strict'])
метод для строк для преобразования типов кодирования.line = 'my big string'
line.encode('ascii', 'ignore')
Для получения дополнительной информации об обработке ASCII и Unicode в Python, это действительно полезный сайт: https://docs.python.org/2/howto/unicode.html
источник
Я думаю, что ответ есть, но только по частям, что затрудняет быстрое решение проблемы, такой как
Давайте рассмотрим пример. Предположим, у меня есть файл, содержащий некоторые данные в следующей форме (содержащие символы ascii и non-ascii)
1/10/17, 21:36 - Земля: Добро пожаловать ��
и мы хотим игнорировать и сохранять только символы ascii.
Этот код будет делать:
и тип (rline) даст вам
источник
Работает для меня
источник
Похоже, вы используете Python 2.x. Python 2.x по умолчанию ascii и не знает о Unicode. Отсюда и исключение.
Просто вставьте строку ниже после Шебанга, она будет работать
источник
coding
Комментарий не волшебная панацея. Вам нужно знать, почему генерируется ошибка, это только исправляет ситуацию, когда в исходном коде Python есть плохие символы. Похоже, это не относится к этому вопросу.