Python >> Tutoriel Python >  >> Python

Analyse XML à l'aide de BeautifulSoup en Python

Présentation

XML est un outil utilisé pour stocker et transporter des données. Il signifie eXtensible Markup Language. XML est assez similaire à HTML et ils ont presque le même type de structure mais ils ont été conçus pour atteindre des objectifs différents.

  • XML est conçu pour transporter données alors que HTML est conçu pour afficher Les données. De nombreux systèmes contiennent des formats de données incompatibles. Cela rend l'échange de données entre des systèmes incompatibles une tâche fastidieuse pour les développeurs Web, car de grandes quantités de données doivent être converties. De plus, il y a des chances que des données incompatibles soient perdues. Mais, XML stocke les données au format texte brut fournissant ainsi une méthode de stockage et de partage de données indépendante du logiciel et du matériel .
  • Une autre différence majeure est que les balises HTML sont prédéfinies alors que les fichiers XML ne le sont pas.

Exemple de XML :

<?xml version="1.0" encoding="UTF-8"?>
<note>
  <to>Harry Potter</to>
  <from>Albus Dumbledore</from>
  <heading>Reminder</heading>
  <body>It does not do to dwell on dreams and forget to live!</body>
</note>

Comme mentionné précédemment, les balises XML ne sont pas prédéfinies, nous devons donc trouver la balise contenant les informations que nous voulons extraire. Ainsi, deux aspects majeurs régissent l'analyse des fichiers XML :

  1. Rechercher les balises requises.
  2. Extraction des données après identification des balises.

Installation de BeautifulSoup et LXML

En ce qui concerne le scraping Web avec Python, BeautifulSoup est la bibliothèque la plus utilisée. La méthode recommandée pour analyser les fichiers XML à l'aide de BeautifulSoup consiste à utiliser lxml de Python analyseur.

Vous pouvez installer les deux bibliothèques en utilisant le pip outil d'installation. Veuillez consulter notre TUTORIEL DE BLOG pour savoir comment les installer si vous souhaitez extraire des données d'un fichier XML à l'aide de Beautiful soup.

# Remarque : Avant de poursuivre notre discussion, veuillez consulter le fichier XML suivant que nous utiliserons tout au long de cet article. (Veuillez créer un fichier avec le nom sample.txt et copiez-collez le code ci-dessous pour vous exercer davantage.)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<CATALOG>
  <PLANT>
    <COMMON>Bloodroot</COMMON>
    <BOTANICAL>Sanguinaria canadensis</BOTANICAL>
    <ZONE>4</ZONE>
    <LIGHT>Mostly Shady</LIGHT>
    <PRICE>$2.44</PRICE>
    <AVAILABILITY>031599</AVAILABILITY>
  </PLANT>
  <PLANT>
    <COMMON>Marsh Marigold</COMMON>
    <BOTANICAL>Caltha palustris</BOTANICAL>
    <ZONE>4</ZONE>
    <LIGHT>Mostly Sunny</LIGHT>
    <PRICE>$6.81</PRICE>
    <AVAILABILITY>051799</AVAILABILITY>
  </PLANT>
  <PLANT>
    <COMMON>Cowslip</COMMON>
    <BOTANICAL>Caltha palustris</BOTANICAL>
    <ZONE>4</ZONE>
    <LIGHT>Mostly Shady</LIGHT>
    <PRICE>$9.90</PRICE>
    <AVAILABILITY>030699</AVAILABILITY>
  </PLANT>
</CATALOG>

Rechercher les balises requises dans le document XML

Les balises n'étant pas prédéfinies en XML, nous devons identifier les balises et les rechercher en utilisant les différentes méthodes fournies par la bibliothèque BeautifulSoup. Maintenant, comment trouver les bonnes balises ? Nous pouvons le faire avec l'aide de BeautifulSoup's méthodes de recherche.

Beautiful Soup a de nombreuses méthodes pour rechercher un arbre d'analyse. Les deux méthodes les plus populaires et couramment utilisées sont :

  1. find()
  2. find_all()

Nous avons un tutoriel de blog complet sur les deux méthodes. Veuillez consulter le didacticiel suivant pour comprendre le fonctionnement de ces méthodes de recherche.

Si vous avez lu l'article mentionné ci-dessus, vous pouvez facilement utiliser le find et find_all  méthodes pour rechercher des balises n'importe où dans le document XML.

Relation entre les balises

Il est extrêmement important de comprendre la relation entre les balises, en particulier lors de l'extraction de données à partir de documents XML.

Les trois relations clés dans l'arborescence d'analyse XML sont :

  • Parent  :balise utilisée comme balise de référence pour accéder aux balises enfants.
  • Enfants  :les balises contenues dans la balise parent.
  • Frères et sœurs  :Comme son nom l'indique, ce sont les balises qui existent au même niveau de l'arborescence d'analyse.

Voyons comment nous pouvons naviguer dans l'arborescence d'analyse XML en utilisant les relations ci-dessus.

Rechercher des parents

❖ Le parent L'attribut nous permet de trouver la balise parent/référence comme indiqué dans l'exemple ci-dessous.

Exemple : Dans le code suivant, nous allons découvrir les parents du common balise.

print(soup.common.parent.name)

Sortie :

plant

Remarque : Le name L'attribut nous permet d'extraire le nom de la balise au lieu d'extraire tout le contenu.

Trouver des enfants

❖ Les enfants L'attribut nous permet de trouver la balise enfant comme indiqué dans l'exemple ci-dessous.

Exemple : Dans le code suivant, nous allons découvrir les enfants du plant balise.

for child in soup.plant.children:
    if child.name == None:
        pass
    else:
        print(child.name)

Sortie :

common
botanical
zone
light
price
availability

Rechercher des frères et sœurs

Une balise peut avoir des frères et sœurs avant et après elle.

  • ❖ Les frères et sœurs précédents L'attribut renvoie les frères et sœurs avant la balise référencée et les next_siblings L'attribut renvoie les frères et sœurs après lui.

Exemple : Le code suivant trouve les balises sœurs précédentes et suivantes du light balise du document XML.

print("***Previous Siblings***")
for sibling in soup.light.previous_siblings:
    if sibling.name == None:
        pass
    else:
        print(sibling.name)

print("\n***Next Siblings***")
for sibling in soup.light.next_siblings:
    if sibling.name == None:
        pass
    else:
        print(sibling.name)

Sortie :

***Previous Siblings***
zone
botanical
common

***Next Siblings***
price
availability

Extraire des données à partir de balises

À présent, nous savons comment naviguer et trouver des données dans les balises. Examinons les attributs qui nous aident à extraire les données des balises.

Attributs de texte et de chaîne

Pour accéder aux valeurs de texte dans les balises, vous pouvez utiliser le text ou strings  attribut.

Exemple : extrayons le texte de la première étiquette de prix en utilisant text et string attributs.

print('***PLANT NAME***')
for tag in plant_name:
    print(tag.text)
print('\n***BOTANICAL NAME***')
for tag in scientific_name:
    print(tag.string)

Sortie :

***PLANT NAME***
Bloodroot
Marsh Marigold
Cowslip

***BOTANICAL NAME***
Sanguinaria canadensis
Caltha palustris
Caltha palustris

L'attribut Contenu

Le contenu L'attribut nous permet d'extraire tout le contenu des balises, c'est-à-dire la balise avec les données. Le contents renvoie une liste, nous pouvons donc accéder à ses éléments en utilisant leur index.

Exemple :

print(soup.plant.contents)
# Accessing content using index
print()
print(soup.plant.contents[1])

Sortie :

['\n', <common>Bloodroot</common>, '\n', <botanical>Sanguinaria canadensis</botanical>, '\n', <zone>4</zone>, '\n', <light>Mostly Shady</light>, '\n', <price>$2.44</price>, '\n', <availability>031599</availability>, '\n']

<common>Bloodroot</common>

Jolie impression du bel objet de soupe

Si vous observez attentivement lorsque nous imprimons les étiquettes à l'écran, elles ont une sorte d'apparence désordonnée. Bien que cela n'ait pas de problèmes de productivité directs, un style d'impression meilleur et structuré nous aide à analyser le document plus efficacement.

Le code suivant montre à quoi ressemble la sortie lorsque nous imprimons normalement l'objet BeautifulSoup :

print(soup)

Sortie :

<?xml version="1.0" encoding="UTF-8" standalone="no"?><html><body><catalog>
<plant>
<common>Bloodroot</common>
<botanical>Sanguinaria canadensis</botanical>
<zone>4</zone>
<light>Mostly Shady</light>
<price>$2.44</price>
<availability>031599</availability>
</plant>
<plant>
<common>Marsh Marigold</common>
<botanical>Caltha palustris</botanical>
<zone>4</zone>
<light>Mostly Sunny</light>
<price>$6.81</price>
<availability>051799</availability>
</plant>
<plant>
<common>Cowslip</common>
<botanical>Caltha palustris</botanical>
<zone>4</zone>
<light>Mostly Shady</light>
<price>$9.90</price>
<availability>030699</availability>
</plant>
</catalog>
</body></html>

Utilisons maintenant le prettify méthode pour améliorer l'apparence de notre sortie.

print(soup.prettify())

Sortie :

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<html>
 <body>
  <catalog>
   <plant>
    <common>
     Bloodroot
    </common>
    <botanical>
     Sanguinaria canadensis
    </botanical>
    <zone>
     4
    </zone>
    <light>
     Mostly Shady
    </light>
    <price>
     $2.44
    </price>
    <availability>
     031599
    </availability>
   </plant>
   <plant>
    <common>
     Marsh Marigold
    </common>
    <botanical>
     Caltha palustris
    </botanical>
    <zone>
     4
    </zone>
    <light>
     Mostly Sunny
    </light>
    <price>
     $6.81
    </price>
    <availability>
     051799
    </availability>
   </plant>
   <plant>
    <common>
     Cowslip
    </common>
    <botanical>
     Caltha palustris
    </botanical>
    <zone>
     4
    </zone>
    <light>
     Mostly Shady
    </light>
    <price>
     $9.90
    </price>
    <availability>
     030699
    </availability>
   </plant>
  </catalog>
 </body>
</html>

La solution finale

Nous sommes maintenant bien familiarisés avec tous les concepts nécessaires pour extraire des données d'un document XML donné. Il est maintenant temps de jeter un œil au code final où nous allons extraire le nom, le nom botanique et le prix de chaque plante dans notre exemple de document XML (sample.xml).

Veuillez suivre les commentaires avec le code ci-dessous pour comprendre la logique utilisée dans la solution.

from bs4 import BeautifulSoup

# Open and read the XML file
file = open("sample.xml", "r")
contents = file.read()

# Create the BeautifulSoup Object and use the parser
soup = BeautifulSoup(contents, 'lxml')

# extract the contents of the common, botanical and price tags
plant_name = soup.find_all('common')  # store the name of the plant
scientific_name = soup.find_all('botanical')  # store the scientific name of the plant
price = soup.find_all('price')  # store the price of the plant

# Use a for loop along with the enumerate function that keeps count of each iteration
for n, title in enumerate(plant_name):
    print("Plant Name:", title.text)  # print the name of the plant using text
    print("Botanical Name: ", scientific_name[
        n].text)  # use the counter to access each index of the list that stores the scientific name of the plant
    print("Price: ",
          price[n].text)  # use the counter to access each index of the list that stores the price of the plant
    print()

Sortie :

Plant Name: Bloodroot
Botanical Name:  Sanguinaria canadensis
Price:  $2.44

Plant Name: Marsh Marigold
Botanical Name:  Caltha palustris
Price:  $6.81

Plant Name: Cowslip
Botanical Name:  Caltha palustris
Price:  $9.90

Conclusion

Les documents XML sont une source importante de transport de données et j'espère qu'après avoir lu cet article, vous serez bien équipé pour extraire les données que vous souhaitez de ces documents. Vous pourriez être tenté de jeter un œil à cette série de vidéos où vous pouvez apprendre à gratter des pages Web.

Veuillez vous abonner et rester à l'écoute pour des articles plus intéressants à l'avenir.


Post précédent
Prochain article