web-dev-qa-db-fra.com

Analyser HTML à l'aide de Python

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.

139
ffledgling

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 .

155
Aadaam

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:

the element selector is 'div#mw-head.noprint'

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')
63
YusuMishi

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
34
Qiau

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

lxml.html Documentation

20
Lenar Hoyt

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)
1
Wesam Na

Je voudrais utiliser EHP

https://github.com/iogf/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
0
Unknown Soldier