2010-06-19 27 views
11

Estoy agregando contenido de algunas fuentes externas y estoy descubriendo que parte contiene errores en su HTML/DOM. Un buen ejemplo sería HTML que falta etiquetas de cierre o atributos de etiqueta malformados. ¿Hay alguna forma de solucionar los errores en Python de forma nativa o en cualquier otro módulo que pueda instalar?Limpiar HTML en Python

+0

¿Alguna de estas respuestas era la que estaba buscando? Si necesita más información, podemos ayudarlo. – JudoWill

+0

@JudoWill: Sí, pude configurar BeautifulSoup y Tidy. Desafortunadamente no estaban captando muchos de los problemas que estaba teniendo. Terminé construyendo mi propia función para pasar por el DOM y solucionar los problemas. ¡Gracias por la ayuda! – Joel

+0

Podría publicar su propia función como respuesta. Este es un problema que tengo mucho tiempo y siempre estoy buscando nuevas soluciones. :) – JudoWill

Respuesta

14

Sugeriría Beautifulsoup. Tiene un analizador maravilloso que puede tratar con etiquetas mal formadas con bastante gracia. Una vez que haya leído en todo el árbol, puede simplemente dar como resultado el resultado.

from BeautifulSoup import BeautifulSoup 
tree = BeautifulSoup(bad_html) 
good_html = tree.prettify() 

Lo he usado muchas veces y funciona de maravilla. Si simplemente está sacando los datos de bad-html, BeautifulSoup realmente brilla cuando se trata de extraer datos.

+1

Tenga cuidado con el rendimiento, BeautifulSoup es muy expansivo. – Tarantula

+1

@Tarantula. Estoy de acuerdo, BeautifulSoup es bastante lento, pero es lo único que he visto que puede analizar algunas de esas tablas locas malformadas basadas en HTML que hay. – JudoWill

+0

Eso es verdad JudoWill. – Tarantula

2

Hay enlaces de python para el HTML Tidy Library Project, pero la limpieza automática de HTML roto es un hueso duro de roer. No es tan diferente de tratar de corregir automáticamente el código fuente; hay demasiadas posibilidades. Todavía tendrá que revisar el resultado y casi con seguridad realizar correcciones adicionales a mano.

1

estoy usando lxml para convertir HTML a XML adecuada (bien formado):

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 ]) 

... y haciendo gran cantidad de eliminación de '' elementos peligrosos en el medio ....

0

Esto se puede hacer utilizando la función tidy_document en el módulo 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) 
2

Aquí es un ejemplo de la limpieza de HTML usando el módulo 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())) 

Mira la docs para obtener una lista completa de opciones que puede pasar al limpiador.