XML-parsering in Python
Dit artikel richt zich op hoe je een bepaald XML-bestand kunt parseren en er op een gestructureerde manier nuttige gegevens uit kunt extraheren. XML: XML staat voor eXtensible Markup Language. Het is ontworpen om gegevens op te slaan en te transporteren. Het is ontworpen om zowel door mensen als door machines leesbaar te zijn. Daarom benadrukken de ontwerpdoelen van XML de nadruk op eenvoud, algemeenheid en bruikbaarheid op internet. Het XML-bestand dat in deze zelfstudie moet worden geparseerd, is eigenlijk een RSS-feed. RSS: RSS (Rich Site Summary, ook wel Real Simple Syndication genoemd) gebruikt een reeks standaard webfeedformaten om regelmatig bijgewerkte informatie te publiceren, zoals blogberichten, nieuwskoppen, audiovideo. RSS is XML-geformatteerde platte tekst.
- Het RSS-formaat zelf is relatief eenvoudig te lezen, zowel door geautomatiseerde processen als door mensen.
- De RSS die in deze tutorial wordt verwerkt, is de RSS-feed van de belangrijkste nieuwsverhalen van een populaire nieuwswebsite. Je kunt het bekijken hier . Ons doel is om deze RSS-feed (of XML-bestand) te verwerken en in een ander formaat op te slaan voor toekomstig gebruik.
#Python code to illustrate parsing of XML files # importing the required modules import csv import requests import xml.etree.ElementTree as ET def loadRSS (): # url of rss feed url = 'http://www.hindustantimes.com/rss/topnews/rssfeed.xml' # creating HTTP response object from given url resp = requests . get ( url ) # saving the xml file with open ( 'topnewsfeed.xml' 'wb' ) as f : f . write ( resp . content ) def parseXML ( xmlfile ): # create element tree object tree = ET . parse ( xmlfile ) # get root element root = tree . getroot () # create empty list for news items newsitems = [] # iterate news items for item in root . findall ( './channel/item' ): # empty news dictionary news = {} # iterate child elements of item for child in item : # special checking for namespace object content:media if child . tag == '{https://video.search.yahoo.com/mrss' : news [ 'media' ] = child . attrib [ 'url' ] else : news [ child . tag ] = child . text . encode ( 'utf8' ) # append news dictionary to news items list newsitems . append ( news ) # return news items list return newsitems def savetoCSV ( newsitems filename ): # specifying the fields for csv file fields = [ 'guid' 'title' 'pubDate' 'description' 'link' 'media' ] # writing to csv file with open ( filename 'w' ) as csvfile : # creating a csv dict writer object writer = csv . DictWriter ( csvfile fieldnames = fields ) # writing headers (field names) writer . writeheader () # writing data rows writer . writerows ( newsitems ) def main (): # load rss from web to update existing xml file loadRSS () # parse xml file newsitems = parseXML ( 'topnewsfeed.xml' ) # store news items in a csv file savetoCSV ( newsitems 'topnews.csv' ) if __name__ == '__main__' : # calling main function main ()
Above code will: - Laad de RSS-feed van de opgegeven URL en sla deze op als een XML-bestand.
- Parseer het XML-bestand om nieuws op te slaan als een lijst met woordenboeken, waarbij elk woordenboek één nieuwsitem is.
- Sla de nieuwsberichten op in een CSV-bestand.
- U kunt meer RSS-feeds bekijken van de nieuwswebsite die in het bovenstaande voorbeeld wordt gebruikt. U kunt proberen een uitgebreide versie van het bovenstaande voorbeeld te maken door ook andere RSS-feeds te parseren.
- Ben je een cricketfan? Dan dit RSS-feed moet van uw interesse zijn! U kunt dit XML-bestand ontleden om informatie over de live cricketwedstrijden te verzamelen en te gebruiken om een desktopmelding te maken!
def loadRSS(): # url of rss feed url = 'http://www.hindustantimes.com/rss/topnews/rssfeed.xml' # creating HTTP response object from given url resp = requests.get(url) # saving the xml file with open('topnewsfeed.xml' 'wb') as f: f.write(resp.content) Here we first created a HTTP response object by sending an HTTP request to the URL of the RSS feed. The content of response now contains the XML file data which we save as topnieuwsfeed.xml in onze lokale map. Volg dit artikel voor meer inzicht in hoe de aanvraagmodule werkt: GET- en POST-verzoeken met Python
Hier gebruiken we xml.etree.ElementTree (noem het kortweg ET) module. Element Tree heeft hiervoor twee klassen: ElementBoom vertegenwoordigt het hele XML-document als een boom en Element vertegenwoordigt een enkel knooppunt in deze boom. Interacties met het hele document (lezen en schrijven naar/van bestanden) vinden meestal plaats op het ElementBoom niveau. Interacties met een enkel XML-element en de subelementen ervan worden uitgevoerd op het Element niveau. Oké, dus laten we door de parseXML() function now: tree = ET.parse(xmlfile)Here we create an ElementBoom object door het doorgegeven bestand te parseren xmlbestand.
root = tree.getroot()getroot() functie retourneert de wortel van boom als een Element object.
for item in root.findall('./channel/item'): Now once you have taken a look at the structure of your XML file you will notice that we are interested only in item element. ./kanaal/item is eigenlijk XPath syntaxis (XPath is een taal voor het adresseren van delen van een XML-document). Hier willen we alles vinden item kleinkinderen van kanaal kinderen van de wortel (aangeduid met '.') element. U kunt meer lezen over de ondersteunde XPath-syntaxis hier . for item in root.findall('./channel/item'): # empty news dictionary news = {} # iterate child elements of item for child in item: # special checking for namespace object content:media if child.tag == '{https://video.search.yahoo.com/mrss': news['media'] = child.attrib['url'] else: news[child.tag] = child.text.encode('utf8') # append news dictionary to news items list newsitems.append(news) Now we know that we are iterating through item elementen waar elk item element bevat één nieuws. Dus creëren we een leegte nieuws dictionary in which we will store all data available about news item. To iterate though each child element of an element we simply iterate through it like this: for child in item:Now notice a sample item element here:
We will have to handle namespace tags separately as they get expanded to their original value when parsed. So we do something like this: if child.tag == '{https://video.search.yahoo.com/mrss': news['media'] = child.attrib['url'] kind.attrib is een woordenboek met alle attributen die verband houden met een element. Hier zijn wij in geïnteresseerd URL attribuut van media: inhoud namespace tag. Now for all other children we simply do: news[child.tag] = child.text.encode('utf8') kindtag bevat de naam van het onderliggende element. kind.tekst stores all the text inside that child element. So finally a sample item element is converted to a dictionary and looks like this: {'description': 'Ignis has a tough competition already from Hyun.... 'guid': 'http://www.hindustantimes.com/autos/maruti-ignis-launch.... 'link': 'http://www.hindustantimes.com/autos/maruti-ignis-launch.... 'media': 'http://www.hindustantimes.com/rf/image_size_630x354/HT/... 'pubDate': 'Thu 12 Jan 2017 12:33:04 GMT ' 'title': 'Maruti Ignis launches on Jan 13: Five cars that threa..... } Then we simply append this dict element to the list nieuwsitems . Tenslotte wordt deze lijst teruggegeven.
Zoals u kunt zien zijn de hiërarchische XML-bestandsgegevens geconverteerd naar een eenvoudig CSV-bestand, zodat alle nieuwsverhalen in de vorm van een tabel worden opgeslagen. Dit maakt het ook eenvoudiger om de database uit te breiden. Ook kan men de JSON-achtige gegevens rechtstreeks in hun applicaties gebruiken! Dit is het beste alternatief voor het extraheren van gegevens van websites die geen openbare API bieden, maar wel enkele RSS-feeds. Alle code en bestanden die in het bovenstaande artikel worden gebruikt, zijn te vinden hier . Wat nu? Dit Vind Je Misschien Leuk
Top Artikelen
Categorie
Interessante Artikelen