Очистка HTML в Python

Я собираю контент из нескольких внешних источников и обнаруживаю, что некоторые из них содержат ошибки в его HTML/DOM. Хорошим примером может быть отсутствие 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)