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

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

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

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

Я хотел бы либо решить его, либо если есть ошибка, пропустите этот сайт. Совет Pls, как я могу это сделать, поскольку я новичок, и сам нижеприведенный код заставил меня написать день. Кстати, сайт, на котором остановился скрипт, был 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" 

По комментариям Марка я изменил код для реализации 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" 

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

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

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

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

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

Акцент мой.

Байт в 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() .

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

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

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