Analyse HTML à L'aide de Python
Je suis à la recherche d'un module D'analyseur HTML pour Python qui peut 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>
Ensuite, il 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 essentiellement lui demander d'obtenir le contenu/texte dans 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 savez qu'il vous donne toutes les balises d'une manière imbriquée comme un arbre.
Je préférerais un module intégré mais cela pourrait demander un peu trop.
Je suis passé par beaucoup de questions sur Stack Overflow et quelques blogs sur internet et la plupart d'entre eux suggèrent BeautifulSoup ou lxml ou HTMLParser mais peu d'entre eux détaillent la fonctionnalité et se terminent simplement comme un débat sur lequel est plus rapide/plus efficace.
7 réponses
Afin que je puisse essentiellement lui demander de me procurer le contenu / texte dans la balise div avec class = 'container' 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-il suffit de lire Comment fonctionne BeautifulSoup. Regardez sa documentation officielle .
Je suppose que ce que vous cherchez est pyquery:
Pyquery: une bibliothèque de type jquery pour python.
Un exemple de ce que vous voulez peut-être comme:
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 inspect de Firefox ou 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 toujours un bon aperçu.
Performance de l'analyseur HTML Python
Je recommande BeautifulSoup même s'il n'est pas intégré. Juste parce que c'est si facile de travailler avec ces types 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
Par rapport aux autres bibliothèques d'analyseurs lxml
est extrêmement rapide:
- http://blog.dispatched.ch/2010/08/16/beautifulsoup-vs-lxml-performance/
- http://www.ianbicking.org/blog/2008/03/python-html-parser-performance.html
Et avec cssselect
c'est assez facile à utiliser pour gratter des pages HTML aussi:
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).
Dans mon expérience belle soupe salit sur un HTML complexe. Je crois que C'est parce que Beautiful Soup n'est pas un analyseur, plutôt un très bon analyseur de chaînes.
Je recommande l'utilisation de justext bibliothèque:
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)
J'utiliserais EHP
Voici:
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