XML-parsing i Python

XML-parsing i Python
Denne artikel fokuserer på, hvordan man kan parse en given XML-fil og trække nogle nyttige data ud af den på en struktureret måde. XML: XML står for eXtensible Markup Language. Det er designet til at gemme og transportere data. Det er designet til at være både menneske- og maskinlæsbart. Det er derfor, designmålene for XML understreger enkelhed og brugervenlighed på tværs af internettet. XML-filen, der skal parses i denne øvelse, er faktisk et RSS-feed. RSS: RSS (Rich Site Summary ofte kaldet Really Simple Syndication) bruger en familie af standard web-feed-formater til at udgive hyppigt opdateret information som blogindlæg, nyhedsoverskrifter, lydvideo. RSS er XML-formateret almindelig tekst.
  • Selve RSS-formatet er relativt let at læse både af automatiserede processer og af mennesker.
  • RSS'en, der behandles i dette selvstudium, er RSS-feedet med topnyhedshistorier fra et populært nyhedswebsted. Du kan tjekke det ud her . Vores mål er at behandle dette RSS-feed (eller XML-fil) og gemme det i et andet format til fremtidig brug.
Python modul brugt: Denne artikel vil fokusere på at bruge indbygget xml modul i python til parsing af XML, og hovedfokus vil være på ElementTree XML API af dette modul. Implementering: Python
   #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:
  • Indlæs RSS-feed fra specificeret URL og gem det som en XML-fil.
  • Parse XML-filen for at gemme nyheder som en liste over ordbøger, hvor hver ordbog er en enkelt nyhed.
  • Gem nyhederne i en CSV-fil.
Lad os prøve at forstå koden i stykker:
    Indlæser og gemmer RSS-feed
    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 topnewsfeed.xml i vores lokale telefonbog. For mere indsigt i, hvordan anmodningsmodulet fungerer, følg denne artikel: GET og POST-anmodninger ved hjælp af Python Parsing af XML Vi har skabt parseXML() funktion til at parse XML-fil. Vi ved, at XML er et iboende hierarkisk dataformat, og den mest naturlige måde at repræsentere det på er med et træ. Se for eksempel på billedet nedenfor: parsing af XML Her bruger vi xml.etree.ElementTree (kald det kort og godt ET) modul. Element Tree har to klasser til dette formål - ElementTree repræsenterer hele XML-dokumentet som et træ og Element repræsenterer en enkelt node i dette træ. Interaktioner med hele dokumentet (læsning og skrivning til/fra filer) foregår normalt på ElementTree niveau. Interaktioner med et enkelt XML-element og dets underelementer udføres på Element niveau. Ok, så lad os gå igennem parseXML() function now:
    tree = ET.parse(xmlfile) 
    Here we create an ElementTree objekt ved at parse det beståede xml-fil.
    root = tree.getroot() 
    getrooted() funktion returnere roden af træ som en 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 punkt element. ./kanal/vare er faktisk XPath syntaks (XPath er et sprog til adressering af dele af et XML-dokument). Her vil vi gerne finde det hele punkt børnebørn af kanal børn af rod (angivet med '.') element. Du kan læse mere om understøttet XPath-syntaks her .
    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 punkt elementer, hvor hver punkt element indeholder én nyhed. Så vi skaber en tom nyheder 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: XML-parsing i Python 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'] 
    barn.attrib er en ordbog over alle attributter relateret til et element. Her er vi interesserede i url egenskab af medie:indhold namespace tag. Now for all other children we simply do:
    news[child.tag] = child.text.encode('utf8') 
    child.tag indeholder navnet på det underordnede element. barn.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 nyhedssider . Endelig er denne liste returneret. Gemmer data til en CSV-fil Nu gemmer vi blot listen over nyheder i en CSV-fil, så den nemt kan bruges eller ændres i fremtiden ved hjælp af gem tilCSV() fungere. For at vide mere om at skrive ordbogselementer til en CSV-fil, gå gennem denne artikel: Arbejde med CSV-filer i Python
Så her er, hvordan vores formaterede data ser ud nu: resultat Som du kan se, er de hierarkiske XML-fildata blevet konverteret til en simpel CSV-fil, så alle nyhedshistorier er gemt i form af en tabel. Dette gør det også lettere at udvide databasen. Man kan også bruge JSON-lignende data direkte i deres applikationer! Dette er det bedste alternativ til at udtrække data fra websteder, der ikke leverer en offentlig API, men som giver nogle RSS-feeds. Al koden og filerne brugt i ovenstående artikel kan findes her . Hvad så?
  • Du kan se flere rss-feeds på nyhedswebstedet, der blev brugt i ovenstående eksempel. Du kan prøve at oprette en udvidet version af ovenstående eksempel ved også at analysere andre rss-feeds.
  • Er du cricketfan? Så denne rss feed skal have din interesse! Du kan parse denne XML-fil for at skrabe information om live cricket-kampene og bruge til at lave en desktop-notifier!
Quiz af HTML og XML Opret quiz