2009-12-17 12 views
51

Da quello che riesco a capire, le due librerie di analisi HTML principali in Python sono lxml e BeautifulSoup. Ho scelto BeautifulSoup per un progetto a cui sto lavorando, ma l'ho scelto senza una ragione particolare se non trovando la sintassi un po 'più facile da imparare e capire. Ma vedo che molte persone sembrano preferire lxml e ho sentito che lxml è più veloce.Analisi HTML in python - lxml o BeautifulSoup? Quale di questi è migliore per quali scopi?

Quindi mi chiedo quali sono i vantaggi di uno rispetto all'altro? Quando dovrei usare lxml e quando dovrei stare meglio usando BeautifulSoup? Ci sono altre biblioteche da prendere in considerazione?

+0

possibile duplicato di [? BeautifulSoup e lxml.html - cosa preferiscono] (http://stackoverflow.com/questions/4967103/beautifulsoup-and-lxml- html-what-to-prefer) Ho scritto una [risposta dettagliata] (http://stackoverflow.com/a/19548832/1243926); ripubblicato qui perché la domanda è duplice. – osa

+0

Scusa, volevo chiudere l'altro. Ora ha contrassegnato l'altro. Ho pensato che non importava dove alzare la bandiera, nella più vecchia o nella più nuova. – osa

risposta

22

Per i principianti, BeautifulSoup non viene più mantenuto attivamente e the author even recommends alternatives come lxml.

Citando dalla pagina collegata:

versione 3.1.0 di Beautiful Soup fa significativamente peggiore su HTML del mondo reale alla versione 3.0.8 fa. Il maggior numero di problemi relativi a è la gestione errata dei tag , errori di "errore iniziale " e errori di "tag di fine non valido". Questa pagina spiega cosa è successo, come sarà risolto il problema e cosa puoi fare adesso.

Questa pagina è stata scritta originariamente in marzo 2009. Da allora, la serie 3.2 è stato rilasciato, la sostituzione delle serie 3.1 , e lo sviluppo della serie 4.x ha ottenuto in corso. Questa pagina rimarrà attiva per gli scopi storici .

tl; dr

Usa 3.2.0 invece.

+9

+1 Non conoscevo il decadimento di BeautifulSoup, su cui faccio affidamento e adoro. –

+1

Bene, lxml dice che ha buone prestazioni, mentre qualcuno qui ha detto che BeautifulSoup ha avuto prestazioni davvero lente. Sembra anche avere API decente. http://codespeak.net/lxml/performance.html – JohnnySoftware

+17

IMHO questo è fuorviante - una lettura attenta di quella pagina rivela che 'lxml' è solo un'alternativa per la versione problematica 3.1.0, i cui problemi sono stati risolti in 3.2. 0, e ora c'è persino la versione 4 sulla strada rilasciata solo 2 mesi fa - quindi il modulo difficilmente "non viene più mantenuto attivamente". * Si prega di modificare la risposta * –

5

Ho usato lxml con grande successo per l'analisi dell'HTML. Sembra anche fare un buon lavoro nel gestire l'HTML "soupy". Lo consiglio vivamente.

Ecco un test rapido che avevo in giro per provare la manipolazione di qualche brutto 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

Non utilizzare BeautifulSoup, utilizzare lxml.soupparser allora sei seduto sulla cima del potere di lxml e può usa i buoni frammenti di BeautifulSoup che è quello di trattare l'HTML veramente spezzato e schifoso.

25

Pyquery fornisce l'interfaccia selettore jQuery a Python (utilizzando lxml sotto il cofano).

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

E 'davvero impressionante, io non uso niente altro più.

+0

Ho sempre voluto provare questa distribuzione. Sembra interessante. –

+0

Funziona meglio di bs4. Ho avuto alcuni problemi con bs4 dove il 'diagnosticare' non funzionava nemmeno :( – Tjorriemorrie

0

Un confronto di velocità un po 'obsoleto può essere trovato here, che consiglia chiaramente lxml, come le differenze di velocità sembrano drastiche.

13

In sintesi, lxml si posiziona come un parser html e xml di qualità di produzione rapidissimo che, tra l'altro, include anche un modulo soupparser per ricorrere alle funzionalità di BeautifulSoup. BeautifulSoup è un progetto di una sola persona, progettato per farti risparmiare tempo per estrarre rapidamente i dati da html o xml di scarsa qualità.

lxml documentation afferma che entrambi i parser presentano vantaggi e svantaggi. Per questo motivo, lxml fornisce un soupparser in modo da poter passare avanti e indietro. Citando,

BeautifulSoup utilizza un approccio di parsing diverso. Non è un vero parser HTML ma usa le espressioni regolari per immergersi nella zuppa tag. È quindi più indulgente in alcuni casi e meno buono in altri. È non raro che lxml/libxml2 analizzi e risolva l'HTML spezzato meglio, ma BeautifulSoup ha il supporto di superiour per il rilevamento della codifica. E ' molto dipende dall'input che il parser funziona meglio.

Alla fine che stanno dicendo,

Lo svantaggio di usare questo parser è che è molto più lento rispetto il parser HTML di lxml. Pertanto, se le prestazioni sono importanti, è possibile che si desideri che consideri l'uso del programma di smistamento solo come riserva per alcuni casi.

Se li ho capito bene, significa che il parser zuppa è più robusto --- si può fare con una "zuppa" di tag malformati, utilizzando le espressioni regolari --- mentre lxml è più semplice e giusto analizza le cose e costruisce un albero come ci si aspetterebbe. Presumo che si applica anche a BeautifulSoup stesso, non solo allo soupparser per lxml.

Essi mostrano anche come a beneficiare di rilevamento codifica BeautifulSoup s', mentre ancora l'analisi rapidamente 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)) 

(Same fonte: http://lxml.de/elementsoup.html).

In parole di creatore BeautifulSoup s',

Questo è tutto! Divertiti! Ho scritto Beautiful Soup per salvare tutti quanti. Una volta che ci si abitua ad esso, dovresti essere in grado di svelare i dati dei siti web mal progettati entro pochi minuti. Inviami una email se hai commenti, problemi o vuoi che tu conosca il tuo progetto che utilizza Beautiful Soup.

--Leonard 

Citato dal Beautiful Soup documentation.

Spero che ora sia chiaro. La zuppa è un brillante progetto in prima persona progettato per farti risparmiare tempo per estrarre i dati da siti Web mal progettati.L'obiettivo è quello di farti risparmiare tempo in questo momento, per portare a termine il lavoro, non necessariamente per farti risparmiare tempo a lungo termine, e sicuramente non per ottimizzare le prestazioni del tuo software.

Inoltre, dal lxml website,

lxml è stato scaricato dal Python Package Index più di due milioni di volte ed è disponibile anche direttamente in molti pacchetto distribuzioni, ad esempio, per Linux o MacOS-X.

E, da Why lxml?,

le librerie C libxml2 e libxslt hanno enormi vantaggi: ... conforme agli standard ... Full-optional ... veloce. veloce! VELOCE! ... lxml è vincolante un nuovo Python per libxml2 e libxslt ...

1

Di sicuro avrei usato EHP. È più veloce di lxml, molto più elegante e semplice da usare.

Check out. 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()  

uscita:

Hello world. 
Problemi correlati