HTML ontleden met Python

Ik ben op zoek naar een HTML Parser-module voor Python die me kan helpen de tags in de vorm van Python-lijsten/woordenboeken/objecten te krijgen.

Als ik een document van het formulier heb:

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

dan zou het me een manier moeten geven om toegang te krijgen tot de geneste tags via de naam of id van de HTML-tag, zodat ik het in principe kan vragen om de inhoud/tekst in de div-tag met class='container'in de body-tag of iets dergelijks.

Als u de functie “Inspecteer element” van Firefox (bekijk HTML) heeft gebruikt, zou u weten dat u alle tags op een mooie geneste manier krijgt, zoals een boom.

Ik heb liever een ingebouwde module, maar dat is misschien wat te veel gevraagd.


Ik heb veel vragen over Stack Overflow en een paar blogs op internet doorgenomen en de meeste stellen BeautifulSoup of lxml of HTMLParser voor, maar weinigen hiervan beschrijven de functionaliteit en eindigen eenvoudig als een discussie over welke sneller/meer is efficiënt.


Antwoord 1, autoriteit 100%

Zodat ik hem kan vragen om de inhoud/tekst in de div-tag met class=’container’ in de body-tag, of iets dergelijks.

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)

Je hebt geen prestatiebeschrijvingen nodig denk ik – lees gewoon hoe BeautifulSoup werkt. Bekijk de officiële documentatie.


Antwoord 2, autoriteit 42%

Ik denk dat je zoekt naar pyquery:

pyquery: een jQuery-achtige bibliotheek voor python.

Een voorbeeld van wat u wilt, kan zijn:

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

En het gebruikt dezelfde selectors als het inspect-element van Firefox of Chrome. Bijvoorbeeld:

de elementselector is 'div#mw-head.noprint'

De geïnspecteerde elementselector is ‘div#mw-head.noprint’. Dus in pyquery hoeft u alleen deze selector door te geven:

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

Antwoord 3, autoriteit 18%

Hier kun je meer lezen over verschillende HTML-parsers in Python en hun prestaties. Ook al is het artikel een beetje gedateerd, het geeft je toch een goed overzicht.

Python HTML-parserprestaties

Ik zou BeautifulSoup aanraden, ook al is het niet ingebouwd. Gewoon omdat het zo gemakkelijk is om mee te werken voor dat soort taken. Bijv.:

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

Antwoord 4, autoriteit 14%

Vergeleken met de andere parserbibliotheken is lxmlextreem snel:

En met cssselectis het ook vrij eenvoudig te gebruiken voor het scrapen van HTML-pagina’s:

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 Documentatie


Antwoord 5, autoriteit 4%

Ik raad lxmlaan voor het ontleden van HTML. Zie “HTML parseren” (op de lxml-site).

Mijn ervaring is dat Beautiful Soup een aantal complexe HTML verprutst. Ik denk dat dat komt omdat Beautiful Soup geen parser is, maar eerder een zeer goede string-analysator.


Antwoord 6

Ik raad aan om de bibliotheek justtextte gebruiken:

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

Gebruik:
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)

Antwoord 7

Ik zou EHP gebruiken

https://github.com/iogf/ehp

Hier is het:

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()

Uitvoer:

Something here
Something else

Other episodes