Je cherche un module d'analyse HTML pour Python qui puisse m'aider à obtenir les balises sous la forme de listes/dictionnaires/objets Python.
Si j'ai un document de la forme:
<html>
<head>Heading</head>
<body attr1='val1'>
<div class='container'>
<div id='class'>Something here</div>
<div>Something else</div>
</div>
</body>
</html>
alors cela devrait me donner un moyen d'accéder aux balises imbriquées via le nom ou l'id de la balise HTML afin que je puisse lui demander de me fournir le contenu/texte de la balise div
avec class='container'
contenu dans la balise body
ou quelque chose de similaire. .
Si vous avez utilisé la fonctionnalité "Inspecter l'élément" de Firefox (voir HTML), vous saurez que toutes les balises vous sont présentées de manière imbriquée, comme un arbre.
Je préférerais un module intégré, mais cela demanderait peut-être un peu trop.
J'ai parcouru de nombreuses questions sur Stack Overflow et sur quelques blogs sur Internet. La plupart d'entre elles suggèrent BeautifulSoup, Lxml ou HTMLParser, mais quelques-unes d'entre elles détaillent les fonctionnalités et finissent simplement par un débat sur celui qui est le plus rapide/le plus efficace.
Pour que je puisse essentiellement lui demander de me procurer le contenu/texte de la balise div avec class = 'conteneur' contenu dans la balise body, ou quelque chose de similaire.
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
Vous n'avez pas besoin de descriptions de performances, je suppose - lisez simplement le fonctionnement de BeautifulSoup. Regardez sa documentation officielle .
Je suppose que ce que vous cherchez, c'est pyquery :
pyquery: une librairie de type jquery pour python.
Voici un exemple de ce que vous voulez:
from pyquery import PyQuery
html = # Your HTML CODE
pq = PyQuery(html)
tag = pq('div#id') # or tag = pq('div.class')
print tag.text()
Et il utilise les mêmes sélecteurs que l'élément inspecter de Firefox ou de Chrome. Par exemple:
Le sélecteur d'élément inspecté est 'div # mw-head.noprint'. Donc dans pyquery, il vous suffit de passer ce sélecteur:
pq('div#mw-head.noprint')
Ici, vous pouvez en savoir plus sur les différents analyseurs HTML en Python et leurs performances. Même si l'article est un peu daté, il vous donne quand même une bonne vue d'ensemble.
Performances de l'analyseur HTML Python
Je recommanderais BeautifulSoup même s'il n'est pas intégré. Simplement parce qu'il est si facile de travailler avec ce genre de tâches. Par exemple:
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
Comparé aux autres bibliothèques d'analyse, lxml
est extrêmement rapide:
Et avec cssselect
, il est également très facile d’utiliser cette fonction pour supprimer des pages HTML:
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'))
Je recommande lxml pour l'analyse HTML. Voir "Analyse HTML" (sur le site lxml).
D'après mon expérience, Beautiful Soup gâche du HTML complexe. Je pense que c'est parce que Beautiful Soup n'est pas un analyseur, mais un très bon analyseur de chaînes.
Je recommande d'utiliser la bibliothèque justext:
https://github.com/miso-belica/jusText
Utilisation: 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)
Je voudrais utiliser EHP
C'est ici:
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()
Sortie:
Something here
Something else