Использование lxml.html с поврежденными html-сущностями - PullRequest
0 голосов
/ 17 июня 2019

Мне нужно работать со страницей, в которой есть неудачное сочетание правильных и неправильных сущностей HTML; например:

<i>Kristj&aacuten V&iacute;ctor</i>

В Firefox 67 это интерпретируется правильно, в конце концов:

ff-htmlent1.png

... однако, если мы сделаем «View Source», Firefox через цвет синтаксиса указывает, что что-то не так с первой сущностью HTML:

ff-htmlent2.png

... и действительно, точка с запятой в конце сущности HTML отсутствует - однако, каким-то образом Firefox выясняет это и отображает правильный символ.

Теперь, если я попытаюсь поработать с этим в lxml:

#!/usr/bin/env python3

import lxml.html as LH
import lxml.html.clean as LHclean

testhtmlstring = "<i>Kristj&aacuten V&iacute;ctor</i>"

myhtml = LH.fromstring( testhtmlstring )
myhtml = LHclean.clean_html( myhtml )
myitem = myhtml.xpath("//i")[0]
myitemstr = myitem.text_content()
print(myitemstr)

... код выводит это на терминал (Ubuntu 18.04):

Kristj&aacuten Víctor

... так что, очевидно, сломанная htmlentity не была преобразована в правильный символ.

Есть ли что-то, что я могу использовать, поэтому я получаю правильный символ в моей выходной строке из lxml, даже в случае нарушения целостности (как это делает Firefox)?

1 Ответ

2 голосов
/ 17 июня 2019

Стандарт HTML 5 определил определенное подмножество сущностей, которые могут быть проанализированы без наличия конечной точки с запятой, поскольку эти сущности исторически были определены с точкой с запятой, являющейся необязательной .

Функция html.unescape() явно поддерживает те, которые используют эту функцию в качестве второго прохода для устранения этой проблемы:

>>> from html import unescape
>>> unescape("Kristj&aacuten Víctor")
'Kristján Víctor'

Если вы установите html5lib, то вы можете заставить lxml вести себя так же, через их lxml.html.html5parser модуль (который включает html5lib собственный html5lib.treebuilders.etree_lxml адаптер ):

>>> from lxml.html import html5parser as etree
>>> etree.fromstring("Kristj&aacuten Víctor").text
'Kristján Víctor'
...