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 :
- Rechercher les balises requises.
- 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 :
-
find()
-
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
et find
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.