Я предполагаю, что ’
должен быть кавычкой.Объект str со значением байта 146, chr(146)
, декодированный с помощью cp1252
, представляет собой кавычку:
In [46]: print(chr(146).decode('cp1252'))
’
Итак, вы можете сделать это:
import lxml.html.clean as clean
import re
html = "<div><!-- word style><bleep><omgz 1,000 tags><--><p>It’s a spicy meatball!</div>"
html=re.sub('&#(\d+);',lambda m: chr(int(m.group(1))).decode('cp1252'),html)
print(html)
# <div><!-- word style><bleep><omgz 1,000 tags><--><p>It’s a spicy meatball!</div>
print(type(html))
# <type 'unicode'>
print(clean.clean_html(html))
# <div><p>It’s a spicy meatball!</p></div>
Или,
doc=lh.fromstring(html)
clean.clean(doc)
Обратите внимание, что кавычка имеет значение кодовой точки Unicode 8217. То есть ord(chr(146).decode('cp1252'))
равно 8217, поэтому lh.tostring
возвращает:
print(lh.tostring(doc))
# <div><p>It’s a spicy meatball!</p></div>
Вы можете перекодировать егов cp1252 вот так:
print(repr(lh.tostring(doc,encoding='cp1252')))
# '<div><p>It\x92s a spicy meatball!</p></div>'
Я не знаю, как уговорить lxml, чтобы вернуть
'<div><p>It’s a spicy meatball!</p></div>'
, чтобы соответствовать выводу вашего кода BeautifulSoup, однако.Что ж, ясно, что это можно сделать с помощью регулярных выражений (полностью изменив то, что я делал выше), но я не знаю, является ли это необходимым или целесообразным, поскольку lxml уже должен возвращать html, который могут понять другие приложения.
result=re.sub('&#(\d+);',lambda m: '&#{n};'.format(
n=ord(unichr(int(m.group(1))).encode('cp1252'))),
lh.tostring(doc))
print(result)
# <div><p>It’s a spicy meatball!</p></div>