2015-01-19 5 views
0

Я пытаюсь создать HTML Parser в Python 3.4.2 на Macbook Air (OS X):Невозможно преобразовать объект '' байтов к Силе неявно HTML Parser Python3 Ошибка

plaintext.py:

from html.parser import HTMLParser 
import urllib.request, formatter, sys 

website = urllib.request.urlopen("http://www.profmcmillan.com") 
data = website.read() 
website.close() 
format = formatter.AbstractFormatter(formatter.DumbWriter(sys.stdout)) 
ptext = HTMLParser(format) 
ptext.feed(data) 
ptext.close() 

Но я получаю следующее сообщение об ошибке:

Traceback (most recent call last): 
    File "/Users/deannarobertazzi/Documents/plaintext.py", line 9, in <module> 
    ptext.feed(data) 
    File "/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/html/parser.py", line 164, in feed 
    self.rawdata = self.rawdata + data 
TypeError: Can't convert 'bytes' object to str implicitly 

Я посмотрел на документацию Python и, видимо, способ разбора данных HTML в Python 3 сильно отличается от выполнения такой вещи в Python 2. Я не Не знаю, как o изменить мой код, чтобы он работал на Python 3. Спасибо.

+1

Какая кодировка заключается в том, что 'data' bytestring использует? Если 'latin-1', например,' ptext.feed (data.decode ('latin-1')) будет работать. Это не очень отличается от Python 2, вы просто должны тщательно различать текст (строки символов Unicode) и байтовые строки (строки произвольных байтов, часто кодирующие текст с помощью различных возможных кодеков) ... что было хорошей идеей но теперь является обязательным :-). –

+1

Я включил UTF-8 в строку ptext.feed (data.decode ('UTF-8)), и он сработал. – brown1001

ответ

0

2.x неявные преобразования работали только тогда, когда все байты были в диапазоне ASCii. [0-127]

>>> u'a' + 'b' 
u'ab' 
>>> u'a' + '\xca' 

Traceback (most recent call last): 
    File "<pyshell#1>", line 1, in <module> 
    u'a' + '\xca' 
UnicodeDecodeError: 'ascii' codec can't decode byte 0xca in position 0: ordinal not in range(128) 

Что часто случалось, и почему это было прекращено, в том, что код будет работать при тестировании с данными ascii, такими как, например, сайт профессора Макмиллана, сегодня, а затем и неудача, например, если проф. Макмиллан должен был добавить заголовок с символом non-ascii, или если использовался другой источник, который не был все-ascii.

В документе doc для HTMLParser.feed(data) указано, что данные должны быть «текстом», который в 3.x означает строку юникода. Таким образом, байты из Интернета должны быть декодированы в unicode. Декодирование сайта с помощью utf-8 работает сегодня, потому что ascii является подмножеством utf-8. Тем не менее, страница в настоящее время имеет

<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=windows-1252"> 

Так что, если не-ASCII символ должны были быть добавлены, и кодирование не изменилось, utf-8 не будет работать. На самом деле нет никакой замены на то, чтобы обратить внимание на кодирование байтов. Как обнаружить или угадать кодирование веб-страницы (при условии, что используется только одна используемая кодировка) является отдельным предметом.