2010-06-19 9 views
11

J'agrégeant le contenu de quelques sources externes et je trouver que certaines d'entre elles contient des erreurs dans son HTML/DOM. Un bon exemple serait HTML manquant des balises de fermeture ou des attributs de balises mal formés. Y at-il un moyen de nettoyer les erreurs dans Python nativement ou des modules tiers que je pourrais installer?Nettoyer HTML en Python

+0

Y avait-il de ces réponses que vous cherchez? Si vous avez besoin de plus d'informations, nous pouvons certainement vous aider? – JudoWill

+0

@JudoWill: Oui, j'ai réussi à faire installer BeautifulSoup et Tidy. Malheureusement, ils n'attrapaient pas beaucoup des problèmes que j'avais. J'ai fini par construire ma propre fonction pour parcourir les DOM et résoudre les problèmes. Merci pour l'aide! – Joel

+0

Pourriez-vous poster votre propre fonction comme réponse. C'est un problème que j'ai beaucoup de temps et je suis toujours à la recherche de nouvelles solutions. :) – JudoWill

Répondre

14

Je suggère Beautifulsoup. Il a un analyseur merveilleux qui peut traiter avec des balises malformées assez gracieusement. Une fois que vous avez lu dans l'arbre entier, vous pouvez simplement afficher le résultat. Je l'ai utilisé plusieurs fois et cela fonctionne à merveille. Si vous sortez simplement les données de bad-html alors BeautifulSoup brille vraiment quand il s'agit de retirer des données.

+1

Soyez prudent avec la performance, BeautifulSoup est très vaste. – Tarantula

+1

@Tarantula. Je suis d'accord, BeautifulSoup est assez lent, mais c'est la seule chose que j'ai jamais vue qui peut analyser certaines de ces tables HTML mal formées. – JudoWill

+0

C'est vrai JudoWill. – Tarantula

2

Il existe des liaisons python pour le HTML Tidy Library Project, mais le nettoyage automatiquement HTML cassé est un coriace. Ce n'est pas si différent d'essayer de réparer automatiquement le code source - il y a juste trop de possibilités. Vous aurez toujours besoin d'examiner la sortie et presque certainement faire d'autres corrections à la main.

1

J'utilise lxml pour convertir le HTML en bonne (bien formé) 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 ]) 

... et de faire beaucoup d'enlever des 'éléments dangereux' au milieu ....

0

Cela peut être fait en utilisant la fonction tidy_document dans le module 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

Voici un exemple de nettoyage HTML à l'aide du module 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())) 

Vérifiez la docs pour une liste complète des options que vous pouvez passer à l'aspirateur.