MooiSoep

Hoe XML-bestanden te parseren met behulp van Python's BeautifulSoup

Hoe XML-bestanden te parseren met behulp van Python's BeautifulSoup
Gegevens zijn letterlijk overal, in allerlei documenten. Maar niet alles is nuttig, vandaar de noodzaak om het te ontleden om de benodigde onderdelen te krijgen. XML-documenten zijn een van die documenten die gegevens bevatten. Ze lijken erg op HTML-bestanden, omdat ze bijna dezelfde soort structuur hebben. Daarom moet je ze ontleden om essentiële informatie te krijgen, net zoals je zou doen wanneer je met HTML werkt.

Er zijn twee belangrijke aspecten aan het ontleden van XML-bestanden:. Zij zijn:

U moet de tag vinden die de gewenste informatie bevat en die informatie vervolgens extraheren. Aan het einde van dit artikel leert u hoe u beide kunt doen wanneer u met XML-bestanden werkt.

Installatie

BeautifulSoup is een van de meest gebruikte bibliotheken als het gaat om webschrapen met Python. Omdat XML-bestanden vergelijkbaar zijn met HTML-bestanden, kan het ze ook ontleden. Om XML-bestanden te ontleden met BeautifulSoup, kunt u het beste gebruik maken van Python's lxml parser.

U kunt beide bibliotheken installeren met de Pip installatietool, via de onderstaande opdracht:

pip installeer bs4 lxml

Om te bevestigen dat beide bibliotheken met succes zijn geïnstalleerd, kunt u de interactieve shell activeren en beide proberen te importeren. Als er geen foutmelding verschijnt, bent u klaar om verder te gaan met de rest van het artikel.

Hier is een voorbeeld:

$python
Python 3.7.4 (tags/v3.7.4:e09359112e, 8 juli 2019, 20:34:20)
[MSC v.1916 64 bit (AMD64)] op win32
Typ "help", "copyright", "credits" of "licentie" voor meer informatie.
>>> bs4 importeren
>>> lxml importeren
>>>

Voordat u verder gaat, moet u een XML-bestand maken van het onderstaande codefragment:. Het is vrij eenvoudig en zou moeten passen bij de gebruiksscenario's waarover u in de rest van het artikel zult leren. Kopieer, plak in je editor en sla op; een naam als monster.xml zou voldoende moeten zijn.



De boom

Eerste
Tweede

Derde

een
Twee
Tweelingen


Vierde

Nu, in je Python-script; je moet het XML-bestand lezen als een normaal bestand en het vervolgens doorgeven aan BeautifulSoup. De rest van dit artikel zal gebruik maken van de bs_content variabele, dus het is belangrijk dat u deze stap zet.

# Importeer BeautifulSoup
van bs4 importeer BeautifulSoup als bs
inhoud = []
# Lees het XML-bestand
met open("voorbeeld.xml", "r") als bestand:
# Lees elke regel in het bestand, readlines() geeft een lijst met regels terug
inhoud = bestand.leesregels()
# Combineer de regels in de lijst tot een string
inhoud = "".meedoen(inhoud)
bs_content = bs(content, "lxml")

Het codevoorbeeld hierboven importeert MooiSoep, dan leest het het XML-bestand als een gewoon bestand. Daarna geeft het de inhoud door aan de geïmporteerde MooiSoep bibliotheek en de parser naar keuze.

U zult merken dat de code niet wordt geïmporteerd lxml. Het hoeft niet zo MooiSoep zal kiezen voor lxml parser als resultaat van passeren "lxml" in het object.

Nu kunt u doorgaan met de rest van het artikel.

Tags zoeken

Een van de belangrijkste fasen van het ontleden van XML-bestanden is het zoeken naar tags. Er zijn verschillende manieren om dit aan te pakken bij het gebruik van BeautifulSoup; dus je moet er een handvol van kennen om over de beste tools voor de juiste situatie te beschikken.

U kunt tags in XML-documenten vinden door:

Tags op naam zoeken

Er zijn twee BeautifulSoup-methoden die u kunt gebruiken bij het zoeken naar tags op naam. De use-cases verschillen echter; laten we ze eens bekijken.

vind

Uit persoonlijke ervaring gebruik je de vind methode vaker gebruiken dan de andere methoden voor het vinden van tags in dit artikel. De find-tag ontvangt de naam van de tag die u wilt krijgen en retourneert een BeautifulSoup-object van de tag als deze er een vindt; anders keert het terug Geen.

Hier is een voorbeeld:

>>> resultaat = bs_content.vind("gegevens")
>>> afdrukken (resultaat)
een
>>> resultaat = bs_content.vind("uniek")
>>> afdrukken (resultaat)
Tweelingen
>>> resultaat = bs_content.vind("vader")
>>> afdrukken (resultaat)
Geen
>>> resultaat = bs_content.vind("moeder")
>>> afdrukken (resultaat)
Geen

Als u naar het voorbeeld kijkt, ziet u dat de vind methode retourneert een tag als deze overeenkomt met de naam, anders retourneert deze Geen. Als je het echter van dichterbij bekijkt, zul je zien dat het slechts één enkele tag retourneert.

Bijvoorbeeld, wanneer? vind(“gegevens”) werd aangeroepen, retourneerde alleen de eerste datatag, maar de andere niet.

GEKOCHT: De vind methode retourneert alleen de eerste tag die overeenkomt met de zoekopdracht.

Dus hoe vind je ook andere tags? Dat leidt ons naar de volgende methode:.

vind alle

De vind alle methode is vrij gelijkaardig aan de vind methode. Het enige verschil is dat het een lijst met tags retourneert die overeenkomen met de zoekopdracht. Als het geen tag vindt, retourneert het gewoon een lege lijst. Vandaar, vind alle zal altijd een lijst retourneren.

Hier is een voorbeeld:

>>> resultaat = bs_content.find_all("gegevens")
>>> afdrukken (resultaat)
[een, Twee]
>>> resultaat = bs_content.find_all("kind")
>>> afdrukken (resultaat)
[Eerste, Tweede,
Derde

een
Twee
Tweelingen

, Vierde]
>>> resultaat = bs_content.find_all("vader")
>>> afdrukken (resultaat)
[]
>>> resultaat = bs_content.find_all("moeder")
>>> afdrukken (resultaat)
[]

Nu u weet hoe u de vind en vind alle methoden, kunt u overal in het XML-document naar tags zoeken. U kunt uw zoekopdrachten echter krachtiger maken.

Hier is hoe:

Sommige tags kunnen dezelfde naam hebben, maar verschillende attributen. Bijvoorbeeld de kind tags hebben een naam attribuut en verschillende waarden. U kunt op basis daarvan specifieke zoekopdrachten uitvoeren.

Kijk eens naar dit:

>>> resultaat = bs_content.find("child", "name": "Rose")
>>> afdrukken (resultaat)
Tweede
>>> resultaat = bs_content.find_all("child", "name": "Rose")
>>> afdrukken (resultaat)
[Tweede]
>>> resultaat = bs_content.find("child", "name": "Jack")
>>> afdrukken (resultaat)
Eerste
>>> resultaat = bs_content.find_all("child", "name": "Jack")
>>> afdrukken (resultaat)
[Eerste]

Je zult zien dat er iets anders is aan het gebruik van de vind en vind alle methoden hier: ze hebben allebei een tweede parameter.

Als je een woordenboek doorgeeft als een tweede parameter, wordt de vind en vind alle methoden bevorderen hun zoektocht om tags te krijgen die attributen en waarden hebben die passen bij het opgegeven sleutel:waarde-paar.

Bijvoorbeeld, ondanks het gebruik van de vind methode in het eerste voorbeeld, retourneerde het de tweede kind tag (in plaats van de eerste kind tag), want dat is de eerste tag die overeenkomt met de zoekopdracht. De vind alle tag volgt hetzelfde principe, behalve dat het alle tags retourneert die overeenkomen met de zoekopdracht, niet alleen de eerste.

Tags zoeken op relatie

Hoewel minder populair dan zoeken op tagnamen, kunt u ook op relaties naar tags zoeken. In de echte zin is het echter meer navigeren dan zoeken.

Er zijn drie belangrijke relaties in XML-documenten:

Uit de bovenstaande uitleg kunt u afleiden dat de referentietag de belangrijkste factor is bij het zoeken naar tags op basis van relaties. Laten we daarom naar de referentietag zoeken en doorgaan met het artikel.

Kijk hier eens even naar:

>>> derde_kind = bs_content.find("child", "name": "Blue Ivy")
>>> afdrukken(derde_kind)

Derde

een
Twee
Tweelingen

Van het bovenstaande codevoorbeeld is de referentietag voor de rest van deze sectie de derde kind tag, opgeslagen in een derde_kind variabele. In de onderstaande subsecties ziet u hoe u naar tags kunt zoeken op basis van hun ouder-, broer of zus- en kinderenrelatie met de referentietag.

Ouders vinden

Om de bovenliggende tag van een referentietag te vinden, gebruikt u de ouder attribuut. Als u dit doet, wordt de bovenliggende tag geretourneerd, evenals de tags eronder. Dit gedrag is heel begrijpelijk, aangezien de onderliggende tags deel uitmaken van de bovenliggende tag.

Hier is een voorbeeld:

>>> resultaat = derde_kind.ouder
>>> afdrukken (resultaat)

Eerste
Tweede

Derde

een
Twee
Tweelingen


Vierde

Kinderen vinden

Om de onderliggende tags van een referentietag te vinden, gebruikt u de kinderen attribuut. Als u dit doet, worden de onderliggende tags geretourneerd, evenals de subtags onder elk ervan. Dit gedrag is ook begrijpelijk, aangezien de kindertags vaak ook hun eigen kindertags hebben.

Een ding dat u moet opmerken is dat de kinderen attribuut retourneert de onderliggende tags als een generator. Dus als je een lijst met onderliggende tags nodig hebt, moet je de generator naar een lijst converteren.

Hier is een voorbeeld:

>>> resultaat = lijst (derde_kind.kinderen)
>>> afdrukken (resultaat)
['\n        Derde\n     ',
een
Twee
Tweelingen
, '\n']

Als u het bovenstaande voorbeeld nader bekijkt, zult u merken dat sommige waarden in de lijst geen tags zijn. Dat is iets waar je op moet letten.

GEKOCHT: De kinderen attribuut retourneert niet alleen de onderliggende tags, het retourneert ook de tekst in de referentietag.

Broers en zussen zoeken

De laatste in deze sectie is het vinden van tags die broers en zussen zijn van de referentietag. Voor elke referentietag kunnen er broer of zus-tags ervoor en erna zijn. De vorige_broers en zussen attribuut zal de broer/zus-tags voor de referentie-tag retourneren, en de volgende_broers en zussen attribuut zal de broer/zus-tags erna teruggeven.

net als de kinderen attribuut, de vorige_broers en zussen en volgende_broers en zussen attributen zullen generatoren retourneren. Dus je moet converteren naar een lijst als je een lijst met broers en zussen nodig hebt.

Kijk hier eens even naar:

>>> previous_siblings = lijst (derde_kind.vorige_broers en zussen)
>>> afdrukken (vorige_broers en zussen)
['\n', Tweede, '\n',
Eerste, '\n']
>>> next_siblings = lijst(derde_kind.volgende_broers en zussen)
>>> print(volgende_broers en zussen)
['\n', Vierde]
>>> print(vorige_broers en zussen + volgende_broers en zussen)
['\n', Tweede, '\n', Eerste,
'\n', '\n', Vierde, '\n']

Het eerste voorbeeld toont de vorige broers en zussen, de tweede toont de volgende broers en zussen; dan worden beide resultaten gecombineerd om een ​​lijst te genereren van alle broers en zussen voor de referentietag.

Extraheren uit tags

Bij het ontleden van XML-documenten zit veel werk in het vinden van de juiste tags. Als je ze echter vindt, wil je misschien ook bepaalde informatie uit die tags halen, en dat is wat deze sectie je zal leren.

U zult zien hoe u het volgende kunt extraheren:

Tagkenmerkwaarden extraheren

Soms heb je een reden om de waarden voor attributen in een tag te extraheren. In de volgende attribuut-waarde-koppeling bijvoorbeeld: naam = "roos", misschien wil je "Rose" extraheren.”

Hiervoor kunt u gebruik maken van de krijgen methode, of toegang krijgen tot de naam van het attribuut met [] als een index, net zoals je zou doen wanneer je met een woordenboek werkt.

Hier is een voorbeeld:

>>> resultaat = derde_kind.get("naam")
>>> afdrukken (resultaat)
Blauwe klimop
>>> resultaat = derde_kind["naam"]
>>> afdrukken (resultaat)
Blauwe klimop

Tagtekst extraheren

Als u toegang wilt tot de tekstwaarden van een tag, kunt u de tekst of snaren attribuut. Beide zullen de tekst in een tag retourneren, en zelfs de kindertags. echter, de tekst attribuut retourneert ze als een enkele string, aaneengeschakeld; Terwijl de snaren attribuut zal ze retourneren als een generator die u kunt converteren naar een lijst.

Hier is een voorbeeld:

>>> resultaat = derde_kind.tekst
>>> afdrukken (resultaat)
'\n    Derde\n      \nEen\nTwee\nTweelingen\n\n'
>>> resultaat = lijst (derde_kind.snaren)
>>> afdrukken (resultaat)
['\n  Derde\n      ', '\n', 'One', '\n', 'Two', '\n', 'Twins', '\n', '\n']

Tag-inhoud extraheren

Naast het extraheren van de attribuutwaarden en tagtekst, kunt u ook alle inhoud van een tag extraheren. Om dit te doen, kunt u de inhoud attribuut; het lijkt een beetje op de kinderen attribuut en zal dezelfde resultaten opleveren. Echter, terwijl de kinderen attribuut retourneert een generator, de inhoud attribuut retourneert een lijst.

Hier is een voorbeeld:

>>> resultaat = derde_kind.inhoud
>>> afdrukken (resultaat)
['\n        Derde\n     ',
een
Twee
Tweelingen
, '\n']

Mooi afdrukken

Tot nu toe heb je enkele belangrijke methoden en attributen gezien die handig zijn bij het ontleden van XML-documenten met BeautifulSoup. Maar als u merkt dat wanneer u de tags op het scherm afdrukt, ze een soort geclusterd uiterlijk hebben. Hoewel het uiterlijk misschien geen directe invloed heeft op uw productiviteit, kan het u helpen om effectiever te analyseren en het werk minder vervelend te maken.

Hier is een voorbeeld van afdrukken op de normale manier:

>>> afdrukken(derde_kind)

Derde

een
Twee
Tweelingen

U kunt het uiterlijk echter verbeteren door de mooier maken methode. Bel gewoon de mooier maken methode op de tag tijdens het afdrukken, en je krijgt iets visueel aantrekkelijks.

Kijk hier eens even naar:

Conclusie

Het ontleden van documenten is een belangrijk aspect van het zoeken naar gegevens. XML-documenten zijn behoorlijk populair en hopelijk bent u beter uitgerust om ze aan te pakken en de gewenste gegevens te extraheren.

Vanuit dit artikel kunt u nu:

Als je je behoorlijk verloren voelt en vrij nieuw bent in de BeautifulSoup-bibliotheek, kun je de BeautifulSoup-zelfstudie voor beginners bekijken.

Hoe u uw gamesessie op Linux kunt vastleggen en streamen
In het verleden werd het spelen van games alleen als een hobby beschouwd, maar met de tijd zag de game-industrie een enorme groei in termen van techno...
Beste spellen om te spelen met handtracking
Oculus Quest introduceerde onlangs het geweldige idee van handtracking zonder controllers. Met een steeds toenemend aantal games en activiteiten die f...
OSD-overlay tonen in Linux-apps en -games op volledig scherm
Het spelen van games op volledig scherm of het gebruik van apps in de modus volledig scherm zonder afleiding kan u afsnijden van relevante systeeminfo...