2009-12-17 22 views
51

Por lo que puedo ver, las dos principales bibliotecas de análisis de HTML en Python son lxml y BeautifulSoup. Elegí BeautifulSoup para un proyecto en el que estoy trabajando, pero lo elegí sin más motivo que encontrar la sintaxis un poco más fácil de aprender y entender. Pero veo que mucha gente parece favorecer a lxml y he escuchado que lxml es más rápido.Analizando HTML en python - lxml o BeautifulSoup? ¿Cuál de estos es mejor para qué tipo de propósitos?

Así que me pregunto cuáles son las ventajas de una sobre la otra? ¿Cuándo quisiera usar lxml y cuándo sería mejor usar BeautifulSoup? ¿Hay alguna otra biblioteca que valga la pena considerar?

+0

posible duplicado de [? BeautifulSoup y lxml.html - qué prefieren] (http://stackoverflow.com/questions/4967103/beautifulsoup-and-lxml- html-what-to-prefer) He escrito una [respuesta detallada] (http://stackoverflow.com/a/19548832/1243926); lo volvió a publicar aquí porque la pregunta es duplicada. – osa

+0

Lo siento, quise cerrar el otro. Ahora marcó el otro. Pensé que no importaba dónde levantar la bandera, en la más antigua o en la más nueva. – osa

Respuesta

22

Para empezar, BeautifulSoup ya no se mantiene activamente, y the author even recommends alternatives como lxml.

Citando de la página enlazada:

Versión 3.1.0 de sopa Hermosa hace significativamente peor en HTML en el mundo real que la versión 3.0.8 hace. Los problemas más comunes de son el manejo incorrecto de etiquetas , errores de "etiqueta de inicio incorrecta " y errores de "etiqueta de finalización incorrecta". Esta página explica lo que sucedió, cómo se abordará el problema y lo que puede hacer ahora mismo.

Esta página fue escrito originalmente en de marzo de 2009. Desde entonces, la serie 3.2 ha sido liberado, en sustitución de la serie 3.1 , y el desarrollo de la serie 4.x ha conseguido en curso. Esta página se mantendrá para fines históricos .

tl; dr

Uso 3.2.0 en su lugar.

+9

+1 No sabía acerca de la decadencia de BeautifulSoup, que confío y adoro. –

+1

Bueno, lxml dice que tiene un buen rendimiento, mientras que alguien aquí dijo que BeautifulSoup tuvo un rendimiento realmente lento. También parece tener una API decente. http://codespeak.net/lxml/performance.html – JohnnySoftware

+17

En mi humilde opinión, esto es engañoso: la lectura cuidadosa de esa página revela que 'lxml' es solo una alternativa para la versión problemática 3.1.0, cuyos problemas se corrigieron en 3.2. 0, y ahora incluso hay una versión 4 en el camino lanzado hace solo 2 meses, por lo que el módulo apenas "ya no se mantiene activamente". * Por favor, modifique la respuesta * –

5

He utilizado lxml con gran éxito para analizar HTML. Parece que también hace un buen trabajo al manejar HTML "espeso". Lo recomiendo encarecidamente

Aquí es una prueba rápida que tenía por ahí para tratar el manejo de algunas fea HTML:

import unittest 
from StringIO import StringIO 
from lxml import etree 

class TestLxmlStuff(unittest.TestCase): 
    bad_html = """ 
     <html> 
      <head><title>Test!</title></head> 
      <body> 
       <h1>Here's a heading 
       <p>Here's some text 
       <p>And some more text 
       <b>Bold!</b></i> 
       <table> 
        <tr>row 
        <tr><td>test1 
        <td>test2 
        </tr> 
        <tr> 
        <td colspan=2>spanning two 
       </table> 
      </body> 
     </html>""" 

    def test_soup(self): 
     """Test lxml's parsing of really bad HTML""" 
     parser = etree.HTMLParser() 
     tree = etree.parse(StringIO(self.bad_html), parser) 
     self.assertEqual(len(tree.xpath('//tr')), 3) 
     self.assertEqual(len(tree.xpath('//td')), 3) 
     self.assertEqual(len(tree.xpath('//i')), 0) 
     #print(etree.tostring(tree.getroot(), pretty_print=False, method="html")) 

if __name__ == '__main__': 
    unittest.main() 
11

No utilice BeautifulSoup, utilice lxml.soupparser entonces usted está sentado en la cima del poder de lxml y puede utiliza los buenos trozos de BeautifulSoup que es lidiar con HTML realmente roto y horrible.

25

Pyquery proporciona la interfaz del selector jQuery a Python (usando lxml debajo del capó).

http://pypi.python.org/pypi/pyquery

Es realmente impresionante, yo no uso nada más.

+0

Siempre quise probar esta versión. Parece interesante. –

+0

Esto funciona mejor que bs4. He tenido algunos problemas con bs4 donde el 'diagnosticado' ni siquiera funcionaba :( – Tjorriemorrie

0

Se puede encontrar una comparación de velocidad algo obsoleta here, que recomienda claramente lxml, ya que las diferencias de velocidad parecen drásticas.

13

En resumen, lxml se posiciona como un analizador html y xml de calidad de producción ultrarrápida que, dicho sea de paso, también incluye un módulo soupparser para recurrir a la funcionalidad de BeautifulSoup. BeautifulSoup es un proyecto para una sola persona, diseñado para ahorrarle tiempo y extraer datos rápidamente de html o xml pobremente formados.

lxml documentation dice que ambos analizadores tienen ventajas y desventajas. Por este motivo, lxml proporciona un soupparser para que pueda alternar. Citando,

BeautifulSoup utiliza un enfoque de análisis diferente. No es un analizador de HTML real , pero usa expresiones regulares para sumergirse en la sopa de etiquetas. Es por lo tanto, más tolerante en algunos casos y menos bueno en otros. Es no es raro que lxml/libxml2 analice y corrija mejor el código HTML roto, , pero BeautifulSoup tiene soporte adicional para la detección de codificación. Es depende mucho de la entrada que el analizador funciona mejor.

En el extremo que están diciendo,

La desventaja de usar este analizador es que es mucho más lento que el analizador de HTML de lxml. Por lo tanto, si el rendimiento es importante, es posible que desee para considerar el uso del analizador de sopa solo como alternativa en determinados casos.

Si los entiendo correctamente, significa que el analizador sopa es más robusto --- se puede tratar con una "sopa" de etiquetas mal formados mediante el uso de expresiones regulares --- mientras que lxml es más sencillo y justo analiza cosas y construye un árbol como era de esperar. Supongo que también se aplica al BeautifulSoup, no solo al soupparser para lxml.

También muestran cómo beneficiarse de la detección de codificación BeautifulSoup 's, sin dejar de analizar rápidamente con lxml:

>>> from BeautifulSoup import UnicodeDammit 

>>> def decode_html(html_string): 
...  converted = UnicodeDammit(html_string, isHTML=True) 
...  if not converted.unicode: 
...   raise UnicodeDecodeError(
...    "Failed to detect encoding, tried [%s]", 
...    ', '.join(converted.triedEncodings)) 
...  # print converted.originalEncoding 
...  return converted.unicode 

>>> root = lxml.html.fromstring(decode_html(tag_soup)) 

(Misma fuente: http://lxml.de/elementsoup.html).

En palabras del creador BeautifulSoup 's,

Eso es todo! ¡Que te diviertas! Escribí Beautiful Soup para ahorrarle tiempo a todos. Una vez que se acostumbre, podrá analizar los datos de sitios web mal diseñados en solo unos minutos. Envíame un correo electrónico si tienes algún comentario, tienes problemas o quieres que sepa sobre tu proyecto que usa Beautiful Soup.

--Leonard 

citado del Beautiful Soup documentation.

Espero que esto ya esté claro. La sopa es un brillante proyecto de una sola persona diseñado para ahorrarle tiempo para extraer datos de sitios web mal diseñados.El objetivo es ahorrarle tiempo en este momento, para hacer el trabajo, no necesariamente para ahorrarle tiempo a largo plazo, y definitivamente no para optimizar el rendimiento de su software.

Asimismo, desde el lxml website,

lxml se ha descargado desde el índice de paquetes Python más de dos millones de veces y también está disponible directamente en muchas distribuciones paquete, por ejemplo, para Linux o MacOS-X.

Y, desde Why lxml?,

las librerías de C libxml2 y libxslt tienen enormes beneficios: ... cumplan con los estándares ... Con todas las funciones ... rápido. ¡rápido! ¡RÁPIDO! ... lxml es un nuevo enlace de Python para libxml2 y libxslt ...

1

Por supuesto, lo usaría EHP. Es más rápido que lxml, mucho más elegante y simple de usar.

Pagar. https://github.com/iogf/ehp

<body ><em > foo <font color="red" ></font></em></body> 


from ehp import * 

data = '''<html> <body> <em> Hello world. </em> </body> </html>''' 

html = Html() 
dom = html.feed(data) 

for ind in dom.find('em'): 
    print ind.text()  

Salida:

Hello world. 
Cuestiones relacionadas