Urllib2 - получить и показать любую языковую страницу, проблема с кодировкой - PullRequest
2 голосов
/ 10 сентября 2010

Я использую Python Google App Engine, чтобы просто получить HTML-страницы и показать их.Моя цель - получить любую страницу на любом языке.Теперь у меня проблема с кодировкой:

Simple

result = urllib2.urlopen(url).read() 

оставляет артефакты вместо специальных букв и

urllib2.urlopen(url).read().decode('utf8')

выдает ошибку:

Кодек 'utf8' не может декодировать байты в позиции 3544-3546: неверные данные

Итак, как это решить?Есть ли какая-нибудь библиотека, которая проверила бы, что такое страница кодирования и конвертировала бы ее, чтобы она была читабельной?

Ответы [ 4 ]

4 голосов
/ 10 сентября 2010

rajax sugested at Как загрузить любую (!) Веб-страницу с правильной кодировкой в ​​python? , чтобы использовать chardet lib из http://chardet.feedparser.org/

Этот код, кажется, теперь работает:

import urllib2
import chardet

def fetch(url):
 try:
    result = urllib2.urlopen(url)
    rawdata = result.read()
    encoding = chardet.detect(rawdata)
    return rawdata.decode(encoding['encoding'])

 except urllib2.URLError, e:
    handleError(e)
2 голосов
/ 10 сентября 2010

Так как это решить?

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

Есть ли какая-нибудь библиотека, которая проверила бы, что такое страница кодирования и конвертировала бы ее так, чтобы она была читабельной?

На самой странице написано, что это за кодировка. Вы можете предположить, что это UTF-8, но это не всегда так.

Если страница представляет собой XML или XHTML, <?xml в начале включает кодировку.

Страница имеет заголовок типа содержимого Content-Type: text/plain; charset="UTF-8", в котором есть кодировка.

Довольно легко правильно декодировать страницу.

Шаг 1. Не предполагайте, что страница имеет формат UTF-8.

Шаг 2. Получить содержимое, прочитать заголовки.

Шаг 3. Используйте кодировку, указанную в заголовке, а не предполагаемую кодировку UTF-8.

1 голос
/ 10 августа 2012

Да, похоже, что urllib2 просто игнорирует атрибут Content-Type.

Поскольку большинство веб-страниц в настоящее время имеют кодировку UTF-8, я просто использую быстрый и грязный метод для обработки ISO-8859-1.страницы.Очевидно, что если вы пытаетесь очистить китайскую страницу, которая не имеет кодировки UTF-8, это не сработает.

Это не красиво, но у меня работает:

def read_url(url):
    reader_req = urllib2.Request(url)
    reader_resp = urllib2.urlopen(reader_req)
    reader_resp_content = reader_resp.read()
    reader_resp.close()

    try:
        return reader_resp_content.decode('utf-8')
    except:
        pass

    try:
        iso_string = reader_resp_content.decode('iso-8859-1')
        print 'UTF-8 decoding failed, but ISO-8859-1 decoding succeeded'
        return iso_string 
    except Exception, e:
        print e
        raise

Изменить: С тех пор я понял, что это слишком много взломать и начал использовать библиотеку запросов, которая, кажется, обрабатывать кодировки просто найти: http://docs.python -requests.org /

r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
t = r.text
0 голосов
/ 10 сентября 2010

Это не дает прямого ответа на ваш вопрос, но я думаю, что urllib2.urlopen в Python 2.5 (и поэтому в App Engine) - беспорядок. Для начала, все коды состояния 2xx, кроме самого 200, выдают исключение (http://bugs.python.org/issue1177).

Я обнаружил, что намного проще извлекать страницы, используя urlfetch от GAE.

...