Я собираю контент из нескольких внешних источников и обнаруживаю, что некоторые из них содержат ошибки в его HTML/DOM. Хорошим примером может быть отсутствие HTML-тегов, закрывающих теги, или неправильные атрибуты тегов. Есть ли способ очистить ошибки в Python изначально или от любых сторонних модулей, которые я мог установить?
Очистка HTML в Python
Ответ 1
Я бы предложил Beautifulsoup. У этого есть замечательный парсер, который может иметь дело с искаженными тегами довольно изящно. После того, как вы прочитали во всем дереве, вы можете просто вывести результат.
from BeautifulSoup import BeautifulSoup
tree = BeautifulSoup(bad_html)
good_html = tree.prettify()
Я использовал это много раз, и он творит чудеса. Если вы просто вытаскиваете данные из bad-html, тогда BeautifulSoup действительно светит, когда дело доходит до вытаскивания данных.
Ответ 2
Существуют привязки python для Проект HTML Tidy Library, но автоматическая очистка сломанного HTML является жесткой гайка для трещин. Это не так сильно отличается от попыток автоматически исправить исходный код - есть слишком много возможностей. Вам все равно нужно просмотреть результат и почти наверняка сделать дальнейшие исправления вручную.
Ответ 3
Вот пример очистки HTML с помощью lxml.html.clean.Cleaner модуль:
import sys
from lxml.html.clean import Cleaner
def sanitize(dirty_html):
cleaner = Cleaner(page_structure=True,
meta=True,
embedded=True,
links=True,
style=True,
processing_instructions=True,
inline_style=True,
scripts=True,
javascript=True,
comments=True,
frames=True,
forms=True,
annoying_tags=True,
remove_unknown_tags=True,
safe_attrs_only=True,
safe_attrs=frozenset(['src','color', 'href', 'title', 'class', 'name', 'id']),
remove_tags=('span', 'font', 'div')
)
return cleaner.clean_html(dirty_html)
if __name__ == '__main__':
with open(sys.argv[1]) as fin:
print(sanitize(fin.read()))
Ознакомьтесь с docs для полного списка параметров, которые вы можете передать в Cleaner.
Ответ 4
Я использую lxml, чтобы преобразовать HTML в правильный (правильно сформированный) XML:
from lxml import etree
tree = etree.HTML(input_text.replace('\r', ''))
output_text = '\n'.join([ etree.tostring(stree, pretty_print=True, method="xml")
for stree in tree ])
... и делает много удаления "опасных элементов" посередине....
Ответ 5
Это можно сделать с помощью функции tidy_document в модуле tidylib.
import tidylib
html = '<html>...</html>'
inputEncoding = 'utf8'
options = {
str("output-xhtml"): True, #"output-xml" : True
str("quiet"): True,
str("show-errors"): 0,
str("force-output"): True,
str("numeric-entities"): True,
str("show-warnings"): False,
str("input-encoding"): inputEncoding,
str("output-encoding"): "utf8",
str("indent"): False,
str("tidy-mark"): False,
str("wrap"): 0
};
document, errors = tidylib.tidy_document(html, options=options)