Analyse HTML en python-lxml ou BeautifulSoup? Lequel d'entre eux est le meilleur pour quels types de fins?

D'après ce que je peux faire, les deux principales bibliothèques D'analyse HTML en Python sont lxml et BeautifulSoup. J'ai choisi BeautifulSoup pour un projet sur lequel je travaille, mais je l'ai choisi sans raison particulière autre que de trouver la syntaxe un peu plus facile à apprendre et à comprendre. Mais je vois que beaucoup de gens semblent favoriser lxml et j'ai entendu dire que lxml est plus rapide.

Je me demande donc quels sont les avantages de l'un par rapport à l'autre? Quand voudrais-je utiliser lxml et quand ferais-je mieux d'utiliser BeautifulSoup? Y a-t-il d'autres bibliothèques à considérer?

52
demandé sur Monika Sulik 2009-12-17 17:08:59

7 réponses

Pour commencer, BeautifulSoup n'est plus activement maintenu, et l'auteur recommande même des solutions de rechange tels que lxml.

Citation de la page liée:

La version 3.1.0 de Beautiful Soup fait significativement pire sur le HTML réel que la version 3.0.8 fait. La plupart des des problèmes de manutention tags incorrectement, " début mal formé tag erreurs", et de "mauvaises " tag" des erreurs. Cette page explique ce qui s'est passé, comment le problème sera de adressée, et ce que vous pouvez faire dès maintenant.

Cette page a été écrite à l'origine en En mars 2009. Depuis lors, la série 3.2 a été publié, remplaçant le 3.1 série, et le développement de la 4.x la série a commencé. Cette page restera pour Historique but.

Tl;dr

Utilisez 3.2.0 à la place.

22
répondu Alex Brasetvik 2011-04-25 02:37:37

Pyquery fournit l'interface jQuery selector à Python (en utilisant lxml sous le capot).

Http://pypi.python.org/pypi/pyquery

C'est vraiment génial, je n'utilise plus rien d'autre.

25
répondu mikeal 2016-03-03 18:40:51

En résumé, lxml se positionne comme un analyseur html et xml de qualité de production ultra-rapide qui, en passant, inclut également un module soupparser pour se replier sur les fonctionnalités de BeautifulSoup. BeautifulSoup est un projet d'une seule personne, conçu pour vous faire gagner du temps pour extraire rapidement des données de html ou xml mal formés.

La documentation Lxml indique que les deux analyseurs ont des avantages et des inconvénients. Pour cette raison, lxml fournit un soupparser afin que vous puissiez basculer d'avant en arrière. Citation,

BeautifulSoup utilise une approche d'analyse différente. Ce N'est pas un vrai HTML parser mais utilise des expressions régulières pour plonger dans Tag soup. Il est donc plus indulgent dans certains cas et moins bon dans d'autres. Il est pas rare que lxml / libxml2 analyse et corrige le HTML cassé mieux, mais BeautifulSoup a un support supérieur pour la détection d'encodage. , Il beaucoup dépend de l'entrée de l'analyseur fonctionne mieux.

En fin de Compte, ils sont en disant:

, L'inconvénient de l'utilisation de cette analyse est qu'il est , beaucoup plus lente, que l'analyseur HTML de lxml. donc, si la performance est importante, vous voudrez peut-être envisager d'utiliser soupparser uniquement comme solution de repli pour certains cas.

Si je les comprends bien, cela signifie que l'analyseur de soupe est plus robuste - - - il peut gérer une "soupe" de balises malformées en utilisant des expressions régulières - - - alors que lxml est plus simple et analyse simplement les choses et construit un arbre que vous attendez. Je suppose que cela s'applique également à BeautifulSoup lui-même, pas seulement au soupparser pour lxml.

Ils montrent également comment bénéficier de la détection d'encodage de BeautifulSoup, tout en continuant à analyser rapidement avec 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))

(Même source: http://lxml.de/elementsoup.html).

Dans les mots du créateur de BeautifulSoup,

C'est ça! Amuse-toi bien! J'ai écrit une belle soupe pour gagner du temps à tout le monde. Une fois que vous vous y habituez, vous devriez être en mesure de se disputer les données de sites Web mal conçus en quelques minutes. Envoyez-moi un email si vous avez des commentaires, des problèmes ou souhaitez-moi savoir à propos de votre projet qui utilise une belle soupe.

 --Leonard

Cité de la documentation Belle soupe .

J'espère que cela est maintenant clair. La soupe est un brillant projet d'une personne conçu pour vous faire gagner du temps pour extraire des données de sites Web mal conçus. Le but est de vous faire gagner du temps en ce moment, pour faire le travail, pas forcément vous faire gagner du temps dans le long terme, et certainement pas pour optimiser les performances de votre logiciel.

Aussi, à partir du site web lxml ,

Lxml a été téléchargé à partir de L'Index du paquet Python plus de deux millions de fois et est également disponible directement dans de nombreux paquet distributions, par exemple pour Linux ou MacOS-X.

Et de Pourquoi lxml?,

Les bibliothèques C libxml2 et libxslt ont des avantage:... Conforme aux normes... Complet... rapide. vite! Vite! ... lxml est une nouvelle liaison Python pour libxml2 et libxslt...

14
répondu osa 2013-10-23 18:25:30

N'utilisez pas BeautifulSoup, utilisez lxml.soupparser Ensuite, vous êtes assis sur le dessus de la puissance de lxml et pouvez utiliser les bons morceaux de BeautifulSoup qui est de traiter le HTML vraiment cassé et merdique.

11
répondu Peter Bengtsson 2013-05-29 12:37:25

J'ai utilisé lxml avec beaucoup de succès pour l'analyse HTML. Il semble faire un bon travail de manipulation "soupy" HTML, aussi. Je recommande vivement il.

Voici un test rapide que j'ai fait traîner pour essayer de gérer un HTML laid:

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()
5
répondu overthink 2009-12-17 14:19:18

Pour sûr, j'utiliserais EHP. Il est plus rapide que lxml, beaucoup plus élégant et plus simple à utiliser.

Vérifier. 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()    

Sortie:

Hello world. 
1
répondu Unknown Soldier 2016-03-20 10:03:18

Une comparaison de vitesse quelque peu dépassée peut être trouvée ici, qui recommande clairement lxml, car les différences de vitesse semblent drastiques.

0
répondu Michael 2012-12-08 13:42:45