• Keine Ergebnisse gefunden

Utilisation du module BeautifulSoup: extraction du texte à partir d'une page htlm ou xlm avec parsing

Exemple 6 : Création d’un fichier HTML et stocker les résultats

3.13. Extraction et gestion des textes a partir des pages html ou xml (pages avec balisages) : utilisation du module ou xml (pages avec balisages) : utilisation du module

3.13.1. Utilisation du module BeautifulSoup: extraction du texte à partir d'une page htlm ou xlm avec parsing

3.13.1.1. Lecture de la page html ou xml

BeautifulSoup est un module permettant de naviguer dans les balises d'une page html ou xml pour renvoyer les informations souhaitées en utilisant un parser.

Exemple introductif: Nous allons télécharger la page suivante http://en.wikipedia.org/wiki/List_of_A_Song_of_Ice_and_Fire_characters en utilisant les outils classiques de lecture d’url comme urllib.request.urlopen() ou requests.

import requests

url =

'http://en.wikipedia.org/wiki/List_of_A_Song_of_Ice_and_Fire_character s'

r = requests.get(url) # Récupérer la page html.

myHtmlText = r.text # Utilisation de la fonction text qui récupère tout le contenu de la page

r.close()

On pouvait aussi utiliser urllib pour lire le contenu import urllib

r =

urllib.request.urlopen("http://en.wikipedia.org/wiki/List_of_A_Song_of _Ice_and_Fire_characters")

myHtmlText =r.read() r.close()

3.13.1.2. Le parsing de la page récupérée

159 Une fois qu'on a récupéré la page, l'étape suivante est de faire du parsing pour récupérer les différentes informations définies par les balises à l'intérieur de la page. Le parsing a pour but de démeler les balises des autres élments de la page. Le but final étant de récupérer le contenu réel de la page. On se sert alors des outils de BeautifulSoup comme suit :

from bs4 import BeautifulSoup

myParsedText = BeautifulSoup(myHtmlText , 'html.parser') # faire du parsing sur le code de la page récupérée.

'html.parser' est le parser utilisé ici. Il est installé par défaut. Il existe plusieurs autres parser.

Par exemple: on peut aussi utiliser lxml comme parser (après avoir installé)

Ci-dessous les parsers couramment utilisés pour le parsing d’une page web avec python

Parser Utilisation observation

html.parser BeautifulSoup(markup,

"html.parser")

installé par défaut sous python

xml BeautifulSoup(markup,

"lxml") module lxml à installer lxml-xml BeautifulSoup(markup,

"lxml-xml") module lxml à installer

lxml-xml BeautifulSoup(markup,

"lxml-xml") module lxml à installer

Exemples :

myParsedText = BeautifulSoup(myHtmlText, 'lxml') # transforme le code du format html au format lxml de BeautifulSoup

print(myParsedText)

print(myParsedText.prettify()) # Afficher le contenu avec indentation:

écrit de manière lisible le code en ecrivant les balises ouvrantes et fermantes sur des lignes séparées du contenu de la balise

print(myParsedText.get_text()) ### Extraire tout le texte brut se trouvant sur la page (sans les balises).

Toutefois get_text laisse des grands espaces dans le texte. C'est pourquoi, il faut faire des traitements supplémentaires pour avoir un texte propre. Pour ces traitements, regarder l'exemple de code qui extrait le texte de la page html sans les balises, les scripts et les espaces (plus bas).

160 Par ailleurs, avant d'appeler get_text, il peut s'avérer nécessaire de supprimer les scripts et les styles présents sur la page parsée. Pour cela, on fait:

for i in myParsedText(["script", "style","form","noscript"]): # on peut allonger cette liste

i.extract() # enlever les scripts, les styles, etc..

print(myParsedText.get_text())

Souvent les éléments à supprimer sont (ces élements proviennent du guide du module patter-web, il faut voir comment les adapter à un traitement direct):

- Strip javascript: supprime tous les élements <script>

- Strip CSS: supprime tous les élements <style>

- Strip comments: supprime tous les élements <!-- -->

- Strip forms: supprime tous les élements <form>

- Strip tags: supprime tous les HTML tags.

- Collapse spaces: remplace les espaces consecutives par un simple espace.

- Collapse linebreaks: remplace les coupures de lignes consecutives par une coupure unique

- Collapse tabs: remplace les espaces tabulations consecutives par un simple espace.

Il existe également d'autres variantes d'utilisation de get_text(). Exemple:

text = myParsedText.get_text(separator=' ') # qui prend le blank comme séparator

On peut aussi utiliser

text = myParsedText.body.get_text() # si l'on veut exclure les textes qui viennent de la base head()

Il faut lire sur la compréhension de la structure des pages html ou xml notamment les balisages (voir plus bas les principales balises)

3.13.1.3. Navigation dans le texte parsé

Une fois que le parsing est fait et que l'objet soup est crée alors, on peut naviguer maintenant dans le texte. Voici ci-dessous quelques exemples :

Exemple 1 :

print(myParsedText.title) # Affichage du titre du document print(myParsedText.title.name) # Affichage nom du titre

print(myParsedText.title.string) # Affichage du texte du titre sans le mot clé title

print(myParsedText.title.parent.name) # base parent de title. Ici c'est head

print(myParsedText.p) # Affichage du premier paragraphe

161 print(myParsedText.a) # Affichage du premier lien hypertexte

print(myParsedText.find_all('a')) #afficher tous les liens hypertexte ou url (a) présents sur la page

print(myParsedText.find(id="link3")) # Recherche la ligne pour laquelle id=link3

Trouver tous les liens (toutes les parentheses de type 'a' qui ont une cle 'href') et créer une liste liens = []

for mytag in myParsedText.find_all('a'):

if mytag.has_attr("href"):

liens.append(mytag["href"]) print(liens)

Trouver le premier tag où la clé id prends valeur PageTop myParsedText.find(id="PageTop")

Déplacer le curseur au bon endroit: recherche par type de tag et paires (clé,valeur) du dictionnaire associé.

noeud = myParsedText.find_all('body')[0]

print(noeud)

Se déplacer à la première parenthèse à l'interieur de la parenthèse actuelle.

premier_fils = list(noeud.children)[0]

Se deplacer à la premiere parenthèse contenant la parenthèse actuelle.

parent = noeud.parent

Extraction de tous les urls se trouvant sur la page

for i in myParsedText.find_all('a'): # Trouver tous les tags de type 'a'

print(i.get('href'))

Exemple 2 : Code qui extrait le texte de la page html sans les balises, les scripts et les espaces import urllib.request

from bs4 import BeautifulSoup

url = "http://news.bbc.co.uk/2/hi/health/2284783.stm"

myHtmlText = urllib.request.urlopen(url).read()

myParsedText = BeautifulSoup(myHtmlText, 'html.parser')

for i in myParsedText(["script", "style"]): # kill all script and style elements

i.extract() # rip it out (enlever les scripts et les styles) cleanText = myParsedText.get_text() # get text

cleanText=cleanText.splitlines() # break into lines (La fonction splitline permet de former une liste formées des lignes du fichier)

162 lines = (line.strip() for line in cleanText) # remove leading and trailing space on each

phraseList = (phrase.strip() for line in lines for phrase in line.split(" ")) # break multi-headlines into a line each

cleanText = '\n'.join(phrase for phrase in phraseList if phrase) # drop blank lines and join phrases with \n as separator

print(cleanText)