Analysieren von HTML mit Python


185

Ich suche nach einem HTML-Parser-Modul für Python, mit dem ich die Tags in Form von Python-Listen / Wörterbüchern / Objekten erhalten kann.

Wenn ich ein Dokument des Formulars habe:

<html>
<head>Heading</head>
<body attr1='val1'>
    <div class='container'>
        <div id='class'>Something here</div>
        <div>Something else</div>
    </div>
</body>
</html>

dann sollte es mir eine Möglichkeit geben, über den Namen oder die ID des HTML-Tags auf die verschachtelten Tags zuzugreifen, damit ich sie grundsätzlich bitten kann, mir den Inhalt / Text im zu erhalten div Tag mit Tag class='container'enthaltenen bodyoder etwas Ähnlichem zu geben.

Wenn Sie die Funktion "Element überprüfen" von Firefox (HTML anzeigen) verwendet haben, wissen Sie, dass Sie alle Tags auf eine schöne verschachtelte Weise wie einen Baum erhalten.

Ich würde ein eingebautes Modul bevorzugen, aber das könnte etwas zu viel verlangen.


Ich habe viele Fragen zu Stack Overflow und ein paar Blogs im Internet durchgesehen und die meisten schlagen BeautifulSoup oder lxml oder HTMLParser vor, aber nur wenige dieser Details beschreiben die Funktionalität und enden einfach als Debatte darüber, welche schneller / effizienter ist.


2
Wie alle anderen Antwortenden würde ich BeautifulSoup empfehlen, da es wirklich gut im Umgang mit kaputten HTML-Dateien ist.
Pascal Rosin

Antworten:


195

Damit ich ihn bitten kann, mir den Inhalt / Text im div-Tag mit class = 'container' zu geben, der im body-Tag enthalten ist, oder etwas Ähnliches.

try: 
    from BeautifulSoup import BeautifulSoup
except ImportError:
    from bs4 import BeautifulSoup
html = #the HTML code you've written above
parsed_html = BeautifulSoup(html)
print(parsed_html.body.find('div', attrs={'class':'container'}).text)

Ich denke, Sie brauchen keine Leistungsbeschreibungen - lesen Sie einfach, wie BeautifulSoup funktioniert. Schauen Sie sich die offizielle Dokumentation an .


2
Was genau ist das parsed_html-Objekt?
Jungvogel

1
parsed_html ist ein BeautifulSoup-Objekt. Stellen Sie es sich wie ein DOMElement oder DOMDocument vor, außer dass es "knifflige" Eigenschaften hat, wie "body" sich auf das BeautifulSoup-Objekt bezieht (denken Sie daran, es ist im Grunde ein Baumknoten) des ersten (und in diesem Fall) , nur) Körperelement des Wurzelelements (in unserem Fall HTML)
Aadaam

18
Nur ein Update: Ab BeautifulSoup 4 ist die Importlinie jetztfrom bs4 import BeautifulSoup
Bailey Parker

2
Allgemeine Informationen: Wenn die Leistung kritisch ist, verwenden Sie lxmlstattdessen besser die Bibliothek (siehe Antwort unten). Mit cssselectes ist sehr nützlich , als gut und die Leistung ist oft 10- bis 100-fach besser als die anderen Bibliotheken zur Verfügung.
Lenar Hoyt

Hinweis: classAttribut ist etwas Besonderes:BeautifulSoup(html).find('div', 'container').text
JFS

85

Ich denke, was Sie suchen, ist Pyquery :

pyquery: eine jquery-ähnliche Bibliothek für Python.

Ein Beispiel dafür, was Sie wollen, könnte sein:

from pyquery import PyQuery    
html = # Your HTML CODE
pq = PyQuery(html)
tag = pq('div#id') # or     tag = pq('div.class')
print tag.text()

Und es werden dieselben Selektoren verwendet wie das Inspect-Element von Firefox oder Chrome. Beispielsweise:

Die Elementauswahl ist 'div # mw-head.noprint'.

Der Selektor für inspizierte Elemente lautet 'div # mw-head.noprint'. In Pyquery müssen Sie nur diesen Selektor übergeben:

pq('div#mw-head.noprint')

2
Ich liebe dich 3000 dafür!
Programmierer

41

Hier können Sie mehr über verschiedene HTML-Parser in Python und deren Leistung lesen. Obwohl der Artikel etwas veraltet ist, gibt er Ihnen dennoch einen guten Überblick.

Leistung des Python-HTML-Parsers

Ich würde BeautifulSoup empfehlen, obwohl es nicht eingebaut ist. Nur weil es so einfach ist, mit solchen Aufgaben zu arbeiten. Z.B:

import urllib2
from BeautifulSoup import BeautifulSoup

page = urllib2.urlopen('http://www.google.com/')
soup = BeautifulSoup(page)

x = soup.body.find('div', attrs={'class' : 'container'}).text

2
Ich war auf der Suche nach etwas, das eher Merkmale / Funktionen als Leistung / Effizienz beschreibt. EDIT: Entschuldigung für die vorzeitige Antwort, dieser Link ist eigentlich gut. Vielen Dank.
Ffledgling

Die ersten
Punktlistenarten

5
Wenn Sie BeautifulSoup4 (neueste Version) verwenden:from bs4 import BeautifulSoup
Franck Dernoncourt

29

Im Vergleich zu den anderen Parser-Bibliotheken lxmlist extrem schnell:

Und damit ist cssselectes auch ganz einfach, HTML-Seiten zu kratzen:

from lxml.html import parse
doc = parse('http://www.google.com').getroot()
for div in doc.cssselect('a'):
    print '%s: %s' % (div.text_content(), div.get('href'))

lxml.html Dokumentation


HTTPS wird nicht unterstützt
Sergio

@Sergio verwenden import requests, Puffer in Datei speichern: stackoverflow.com/a/14114741/1518921 (oder urllib), nach dem Laden der gespeicherten Datei mit Parse,doc = parse('localfile.html').getroot()
Guilherme Nascimento

Ich analysiere riesige HTMLs für bestimmte Daten. Das Ausführen mit BeautifulSoup dauerte 1.7Sekunden, aber das Anwenden von lxml hat es fast um das *100SCHNELLE beschleunigt! Wenn Sie Wert auf Leistung legen, ist lxml die beste Option
Alex-Bogdanov

9

Ich empfehle lxml zum Parsen von HTML. Siehe "HTML analysieren" (auf der lxml-Site).

Nach meiner Erfahrung bringt Beautiful Soup komplexes HTML durcheinander. Ich glaube, das liegt daran, dass Beautiful Soup kein Parser ist, sondern ein sehr guter String-Analysator.


3
AIUI Schöne Suppe kann mit dem meisten „Back - End“ XML - Parser zur Arbeit gemacht wird, scheint lxml eines der unterstützten Parser zu sein crummy.com/software/BeautifulSoup/bs4/doc/#installing-a-parser
ffledgling

@ffledgling Einige Funktionen von BeautifulSoup sind jedoch ziemlich träge.
Lenar Hoyt

2

Ich empfehle die Verwendung der Justext- Bibliothek:

https://github.com/miso-belica/jusText

Verwendung: Python2:

import requests
import justext

response = requests.get("http://planet.python.org/")
paragraphs = justext.justext(response.content, justext.get_stoplist("English"))
for paragraph in paragraphs:
    print paragraph.text

Python3:

import requests
import justext

response = requests.get("http://bbc.com/")
paragraphs = justext.justext(response.content, justext.get_stoplist("English"))
for paragraph in paragraphs:
    print (paragraph.text)

0

Ich würde EHP verwenden

https://github.com/iogf/ehp

Hier ist es:

from ehp import *

doc = '''<html>
<head>Heading</head>
<body attr1='val1'>
    <div class='container'>
        <div id='class'>Something here</div>
        <div>Something else</div>
    </div>
</body>
</html>
'''

html = Html()
dom = html.feed(doc)
for ind in dom.find('div', ('class', 'container')):
    print ind.text()

Ausgabe:

Something here
Something else

5
Bitte erkläre. Was würden Sie EHP über die beliebte BeautifulSoup oder lxml verwenden?
ChaimG
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.