Подтвердить что ты не робот

Utf8-кодек не может декодировать байт 0x96 в python

Я пытаюсь проверить, существует ли определенное слово на странице для многих сайтов. script работает нормально, скажем, 15 сайтов, а затем останавливается.

UnicodeDecodeError: кодек 'utf8' не может декодировать байт 0x96 в позиции 15344: недопустимый стартовый байт

Я сделал поиск в stackoverflow и нашел много проблем, но я не могу понять, что пошло не так в моем случае.

Я хотел бы либо решить его, либо, если есть ошибка, пропустите этот сайт. Совет Pls, как я могу это сделать, поскольку я новичок, и сам нижеприведенный код заставил меня написать день. Кстати, сайт, на котором остановился script, был http://www.homestead.com

filetocheck = open("bloglistforcommenting","r")
resultfile = open("finalfile","w")

for countofsites in filetocheck.readlines():
        sitename = countofsites.strip()
        htmlfile = urllib.urlopen(sitename)
        page = htmlfile.read().decode('utf8')
        match = re.search("Enter your name", page)
        if match:
            print "match found  : " + sitename
            resultfile.write(sitename+"\n")

        else:
            print "sorry did not find the pattern " +sitename

print "Finished Operations"

В соответствии с комментариями Mark я изменил код для реализации beautifulsoup

htmlfile = urllib.urlopen("http://www.homestead.com")
page = BeautifulSoup((''.join(htmlfile)))
print page.prettify() 

теперь я получаю эту ошибку

page = BeautifulSoup((''.join(htmlfile)))
TypeError: 'module' object is not callable

Я пытаюсь их быстро начать пример из http://www.crummy.com/software/BeautifulSoup/documentation.html#Quick%20Start. Если я скопирую его, то код будет работать нормально.

Я НАКОНЕЦ получил его на работу. Спасибо за вашу помощь. Вот окончательный код.

import urllib
import re
from BeautifulSoup import BeautifulSoup

filetocheck = open("listfile","r")

resultfile = open("finalfile","w")
error ="for errors"

for countofsites in filetocheck.readlines():
        sitename = countofsites.strip()
        htmlfile = urllib.urlopen(sitename)
        page = BeautifulSoup((''.join(htmlfile)))  
        pagetwo =str(page) 
        match = re.search("Enter YourName", pagetwo)
        if match:
            print "match found  : " + sitename
            resultfile.write(sitename+"\n")

        else:
            print "sorry did not find the pattern " +sitename

print "Finished Operations"
4b9b3361

Ответ 1

Многие веб-страницы закодированы неправильно. Для анализа HTML попробуйте BeautifulSoup, так как он может обрабатывать множество типов неверных HTML, которые находятся в дикой природе.

Beautiful Soup - это парсер HTML/XML Python, предназначенный для быстрого оборотные проекты, такие как скрипинг экрана. Три функции делают это мощный:

  • Красивый суп не задохнется, если вы дадите ему плохую разметку. Это дает дерево разбора, которое делает примерно такое же значение, как и ваш оригинал документ. Обычно это достаточно хорошо для сбора необходимых данных и убежать.

  • Beautiful Soup предлагает несколько простых методов и Pythonic идиомы для навигации, поиска и изменения дерева синтаксического анализа: a инструментарий для анализа документа и извлечения необходимого вам. Вы не нужно создавать собственный парсер для каждого приложения.

  • Красивые Суп автоматически конвертирует входящие документы в Юникод и исходящие документы для UTF-8. Вам не нужно думать о кодировках, если только в документе не указывается кодировка, а Beautiful Soup не может автоопределить один. Тогда вам просто нужно указать исходную кодировку.

Акцент на мой.

Ответ 2

Байт в 15344 равен 0x96. Предположительно, в позиции 15343 имеется либо однобайтная кодировка символа, либо последний байт многобайтовой кодировки, что делает 15344 началом символа. 0x96 находится в двоичном коде 10010110, и любой байт, соответствующий шаблону 10XXXXXX (от 0x80 до 0xBF), может быть только вторым или последующим байтом в кодировке UTF-8.

Следовательно, поток является либо не UTF-8, либо поврежден.

Изучая URI, на который вы ссылаетесь, мы находим заголовок:

Content-Type: text/html

Поскольку не указано кодирование, мы должны использовать по умолчанию для HTTP, который является ISO-8859-1 (также известный как "Latin 1" ).

Изучая содержимое, находим строку:

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

Это механизм возврата для людей, которые по какой-то причине неспособны правильно настроить заголовки HTTP. На этот раз нам явно сказано, что кодировка символов - это ISO-8859-1.

Как таковой, нет никаких оснований ожидать, что он прочитает его как UTF-8.

Для дополнительного удовольствия, хотя, если учесть, что в ISO-8859-1 0x96 кодируется U + 0096, который является управляющим символом "НАЧАЛО ОХРАННОЙ ЗОНЫ", мы обнаруживаем, что ISO-8859-1 неверен либо. Кажется, люди, создавшие страницу, сделали с вами аналогичную ошибку.

Из контекста, казалось бы, они фактически использовали Windows-1252, так как в этой кодировке 0x96 кодирует U + 2013 (EN-DASH, выглядит как ).

Итак, чтобы проанализировать эту конкретную страницу, которую вы хотите декодировать в Windows-1252.

В общем, вы хотите исследовать заголовки при выборе кодировок символов, и хотя в этом случае это может быть неверно (или, может быть, не более, несколько кодеков ISO-8859-1 на самом деле являются Windows-1252) вы будете правы чаще. Вам все равно нужно что-то уловить, как это, читая резервную копию. Метод decode принимает второй параметр errors. По умолчанию используется 'strict', но вы также можете иметь 'ignore', 'replace', 'xmlcharrefreplace' (не подходит), 'backslashreplace' (не подходит), и вы можете зарегистрировать собственный обработчик возврата с помощью codecs.register_error().

Ответ 3

Сайт "http://www.homestead.com" не претендует на отправку вам utf-8, на самом деле ответ считается iso-8859-1:

<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">

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