Каков тип содержимого/кодировка по умолчанию?

В соответствии с этим ответом: urllib2 читается в Юникоде

Мне нужно получить тип контента, чтобы перейти в unicode. Однако на некоторых сайтах нет "кодировки".

Например, ['content-type'] для эта страница является "text/html". Я не могу преобразовать его в unicode.

encoding=urlResponse.headers['content-type'].split('charset=')[-1]
htmlSource = unicode(htmlSource, encoding)
TypeError: 'int' object is not callable

Есть ли по умолчанию "кодировка" (на английском, конечно)... так что, если ничего не найдено, я могу просто использовать это?

Ответы

Ответ 1

Есть ли по умолчанию "кодировка" (на английском, конечно)... так что, если ничего не найдено, я могу просто использовать это?

Нет, нет. Вы должны догадаться.

Тривиальный подход: попробуйте и расшифруйте как UTF-8. Если это сработает, то это, скорее всего, UTF-8. Если это не так, выберите наиболее вероятную кодировку для типов страниц, которые вы просматриваете. Для англоязычных страниц, которые cp1252, кодировка Windows западноевропейских стран. (Что похоже на ISO-8859-1, фактически большинство браузеров будут использовать cp1252 вместо iso-8859-1, даже если вы укажете эту кодировку, поэтому стоит дублировать это поведение.)

Если вам нужно угадать другие языки, он становится очень волосатым. Существуют существующие модули, которые помогут вам угадать в этих ситуациях. См. Например. chardet.

Ответ 2

Ну, я просто просмотрел данный URL-адрес, который перенаправляется на

http://www.engadget.com/2009/11/23/apple-hits-back-at-verizon-in-new-iphone-ads-video

затем нажмите Crtl-U (источник просмотра) в FireFox, и он показывает

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

@Konrad: что вы имеете в виду "кажется, как будто... использует ISO-8859-1"??

@alex: что заставляет вас думать, что у него нет "charset"?

Посмотрите на код, который у вас есть (мы GUESS - это строка, вызывающая ошибку (всегда показывайте FULL traceback и сообщение об ошибке!)):

htmlSource = unicode(htmlSource, encoding)

и сообщение об ошибке:

TypeError: 'int' object is not callable

Это означает, что unicode не относится к встроенной функции, это относится к int. Я помню, что в вашем другом вопросе у вас было что-то вроде

if unicode == 1:

Я предлагаю вам использовать другое имя для этой переменной - например use_unicode.

Дополнительные предложения: (1) всегда показывать достаточно кода для воспроизведения ошибки (2) всегда читайте сообщение об ошибке.

Ответ 3

В теории кодировка по умолчанию ISO-8859-1. Но часто на это нельзя положиться. Веб-сайты, которые не отправляют явную кодировку, заслуживают выговора. Позаботьтесь о том, чтобы отправить сердитое письмо веб-мастеру Endgadget?

Ответ 4

htmlSource=htmlSource.decode("utf8") должен работать в большинстве случаев, за исключением того, что вы сканируете сайты, не являющиеся английскими.

или вы могли бы написать функцию декодирования силы, подобную этой

def forcedecode(text):
    for x in ["utf8","sjis","cp1252","utf16"]:
        try:return text.decode(x)
        except:pass
    return "Unknown Encoding"

Ответ 5

Если нет явного типа содержимого, он должен быть ISO-8859-1, как указано ранее в ответах. К сожалению, это не всегда так, поэтому разработчики браузера потратили некоторое время на получение алгоритмов, которые пытаются угадать тип контента на основе содержимого вашей страницы.

К счастью для вас, Марк Пилигрим проделал всю тяжелую работу по переносу реализации firefox на python в виде chardet module. Его описание о том, как он работает для одной из глав Dive Into Python 3, также стоит прочитать.