scraping read parser htmlparser python html algorithm xhtml

read - python html scraping



¿Cómo soluciono las etiquetas HTML anidadas/no cerradas incorrectamente? (4)

Necesito desinfectar el HTML enviado por el usuario cerrando las etiquetas abiertas con el orden de anidación correcto. He estado buscando un algoritmo o código de Python para hacer esto, pero no he encontrado nada, excepto algunas implementaciones a medias en PHP, etc.

Por ejemplo, algo así como

<p> <ul> <li>Foo

se convierte

<p> <ul> <li>Foo</li> </ul> </p>

Cualquier ayuda sería apreciada :)


Ejecútelo a través de Tidy o una de sus bibliotecas portadas.

Intente codificarlo a mano y querrá sacarle los ojos.


usando BeautifulSoup:

from BeautifulSoup import BeautifulSoup html = "<p><ul><li>Foo" soup = BeautifulSoup(html) print soup.prettify()

te lleva

<p> <ul> <li> Foo </li> </ul> </p>

Por lo que yo sé, no puedes controlar colocar las etiquetas <li> </ li> en líneas separadas de Foo.

usando Tidy:

import tidy html = "<p><ul><li>Foo" print tidy.parseString(html, show_body_only=True)

te lleva

<ul> <li>Foo</li> </ul>

Desafortunadamente, no conozco ninguna forma de mantener la etiqueta <p> en el ejemplo. Tidy lo interpreta como un párrafo vacío en lugar de uno sin cerrar, por lo que

print tidy.parseString(html, show_body_only=True, drop_empty_paras=False)

sale como

<p></p> <ul> <li>Foo</li> </ul>

En última instancia, por supuesto, la etiqueta <p> en su ejemplo es redundante, por lo que puede estar bien perderla.

Finalmente, Tidy también puede sangrar:

print tidy.parseString(html, show_body_only=True, indent=True)

se convierte

<ul> <li>Foo </li> </ul>

Todos estos tienen sus altibajos, pero con suerte uno de ellos está lo suficientemente cerca.


Justo ahora, obtuve un html en el que lxml y pyquery no funcionaban bien, parece que hay algunos errores en el html. Como Tidy no es fácil de instalar en Windows, elijo BeautifulSoup . Pero encontré eso:

from BeautifulSoup import BeautifulSoup import lxml.html soup = BeautifulSoup(page) h = lxml.html(soup.prettify())

actuar igual que h = lxml.html(page)

Lo que realmente soluciona mi problema es soup = BeautifulSoup(page, ''html5lib'') .
html5lib debe instalar html5lib y luego usarlo como analizador en BeautifulSoup . html5lib analizador html5lib parece funcionar mucho mejor que otros.

Espero que esto pueda ayudar a alguién.


usa html5lib, ¡funciona genial! Me gusta esto.

soup = BeautifulSoup (datos, ''html5lib'')