56 votes

Analyser HTML en python - lxml ou BeautifulSoup? Lequel de ceux-ci est meilleur pour quels types de buts?

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

Alors je me demandais quels sont les avantages de l'un sur l'autre? Quand je veux utiliser lxml et quand j'ai mieux à l'aide de BeautifulSoup? Existe-il d'autres bibliothèques vaut la peine d'examiner?

26voto

mikeal Points 2898

pyquery fournit l'interface de sélecteur jquery à 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.

22voto

Alex Brasetvik Points 5314

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

Citation de la page du lien:

La Version 3.1.0 de Belle Soupe n' bien pire sur le monde réel HTML que la version 3.0.8 n'. La plupart des des problèmes de manutention les tags, "mal formé début tag erreurs", et de "mauvaises " tag" des erreurs. Cette page explique ce qui s'est passé, comment le problème sera abordé, et ce que vous pouvez faire dès maintenant.

Cette page a été écrite à l'origine en En mars 2009. Depuis, le 3.2 de la série a été publié, en remplacement de la 3.1 de la série, et le développement de l'4.x la série a commencé. Cette page restera historique pour fins.

tl;dr

Utilisation 3.2.0 à la place.

16voto

Sergey Orshanskiy Points 1180

En résumé, lxml se positionne comme un ultra-rapide de la production-la qualité de l'html et xml parser, qui, par ailleurs, comprend également un soupparser module de retomber sur BeautifulSoup sa fonctionnalité. BeautifulSoup est un projet conçu pour vous faire économiser du temps à s'en extraire rapidement des données en html mal formé ou xml.

lxml la documentation dit que les deux analyseurs ont des avantages et des inconvénients. Pour cette raison, lxml fournit un soupparser de sorte que vous pouvez basculer d'avant en arrière. Citant,

BeautifulSoup utilise une autre approche d'analyse. Ce n'est pas un réel HTML analyseur mais utilise des expressions régulières pour plonger dans la soupe de tags. Il est donc plus indulgent dans certains cas et moins bon dans d'autres. Il est pas rare que lxml/libxml2 analyse et résout rompu HTML mieux, mais BeautifulSoup est supérieure de support pour le codage de détection. Il beaucoup dépend de l'entrée de l'analyseur fonctionne mieux.

À la fin ils disent,

L'inconvénient de l'utilisation de cette analyse est qu'il est beaucoup plus lentque l'analyseur HTML de lxml. Donc, si la performance est importante, vous pourriez vouloir envisager l'utilisation de soupparser seulement comme une solution de repli pour certains cas.

Si je comprends correctement, cela signifie que la soupe de l'analyseur est plus robuste --- il peut traiter avec une "soupe" de la malformation de balises à l'aide d'expressions régulières --- alors qu' lxml est plus simple et juste analyse les choses et construit un arbre que vous attendez. Je suppose qu'il s'applique également à l' BeautifulSoup lui-même, et pas seulement à l' soupparser pour lxml.

Ils montrent également comment bénéficier de l' BeautifulSoups'encodage de détection, tout en continuant l'analyse 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).

En termes de BeautifulSoups'créateur,

Ça y est! Amusez-vous! J'ai écrit Belle Soupe pour économiser du temps tout le monde. Une fois que vous vous habituez à elle, vous devriez être en mesure de disputer des données de mal conçu des sites web 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 la Belle Soupe.

 --Leonard

Cité de la Belle Soupe de documentation.

J'espère que c'est clair maintenant. La soupe est un brillant d'une personne de projet conçu pour vous faire économiser du temps à extraire des données de mal-conçu des sites web. L'objectif est de vous faire économiser le temps en ce moment, pour faire le travail, pas nécessairement de gagner du temps dans le long terme, et certainement pas pour optimiser les performances de votre logiciel.

Aussi, à partir de la lxml site web,

lxml a été téléchargé à partir du Python Package Index de plus de deux des millions de fois et est également disponible directement dans de nombreux package les distributions, par exemple pour Linux ou MacOS-X.

Et, à partir de Pourquoi lxml?,

Les bibliothèques C libxml2 et libxslt ont d'énormes avantages:... Conforme aux normes... Complète... rapide. vite! VITE! ... lxml est un nouveau binding Python pour libxml2 et libxslt...

11voto

Peter Bengtsson Points 1180

N'utilisez pas BeautifulSoup, utilisez lxml.soupparser, alors vous êtes au sommet de la puissance de Lxml et pouvez utiliser les bons éléments de BeautifulSoup, qui consiste à traiter du code HTML vraiment cassé et de mauvaise qualité.

5voto

overthink Points 9471

J'ai utilisé lxml avec un grand succès pour l'analyse HTML. Il semble faire un bon travail de gestion du HTML "soupy", aussi. Je le recommande fortement.

Voici un rapide test que je traînais pour essayer de manipuler un HTML très 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()
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X