Ярлыки

2008-10-09

Кодировка в html5lib

Есть такая замечательная библиотека html5lib, а предназначена она для обработки, в том числе не валидного (не корректного) HTML. Пакет так же имеет код для сериализации DOM, ElementTree, BeautifulSoup и другой хрени в HTML, но этой его частью я не пользуюсь.

Вот простенький пример, для парсинга HTML в DOM:

from html5lib.html5parser import HTMLParser
from html5lib.treebuilders.dom import TreeBuilder

dom = HTMLParser(tree = TreeBuilder).parse(html)
Где html — файловый объект или строка. Собственно это все.

Следует отметить, что это замечательная библиотека в состоянии самостоятельно определить кодировку документа одним из нескольких способов, в том числе «самым правильным», используя значение тега meta. Но вот незадача, «самый правильный» способ берет только первые 512 байт для анализа и, если заголовок большой и тег с указанием кодировки находится за границей в 512 байт, то кодировку определить нет шансов.

Решить проблему можно таким вот хаком:
from html5lib.inputstream import HTMLInputStream

HTMLInputStream.numBytesMeta = property(
lambda self: 1024,
lambda self, value: None)
HTMLInputStream.numBytesChardet = property(
lambda self: 2048,
lambda self, value: None)

del HTMLInputStream
Где numBytesMeta это и есть ограничение при сканировании meta, а numBytesChardet это ограничение при сканировании HTML другим методом, какой анализ проводится, я не разбирался. Эти атрибуты настраиваются при инициализации экземпляра HTMLInputStream и тут же используются, так что другого способа перекрыть эти значения нет, не считая, конечно, варианта с переопределением и полным переписыванием метода __init__ и использованием «хитрых свойств». Я умолчал про цифры в лямбдах, но вы и сами о их смысле догадываетесь.