Analiza XML în Python
Acest articol se concentrează asupra modului în care se poate analiza un anumit fișier XML și extrage câteva date utile dintr-un mod structurat. XML: XML înseamnă eXtensible Markup Language. A fost conceput pentru a stoca și transporta date. A fost conceput pentru a fi citit atât de om, cât și de mașină. De aceea, obiectivele de proiectare ale XML subliniază generalitatea simplității și utilitatea pe internet. Fișierul XML care urmează să fie analizat în acest tutorial este de fapt un flux RSS. RSS: RSS (Rezumatul site-ului bogat numit adesea Syndication cu adevărat simplă) folosește o familie de formate standard de flux web pentru a publica informații actualizate frecvent, cum ar fi intrările de blog, titlurile de știri, video audio. RSS este text simplu format XML.
- Formatul RSS în sine este relativ ușor de citit atât prin procese automate, cât și de către oameni deopotrivă.
- RSS-ul procesat în acest tutorial este fluxul RSS al știrilor de top de pe un site de știri popular. Îl poți verifica Aici . Scopul nostru este de a procesa acest flux RSS (sau fișier XML) și de a-l salva într-un alt format pentru utilizare ulterioară.
#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: - Încărcați fluxul RSS de la adresa URL specificată și salvați-l ca fișier XML.
- Analizați fișierul XML pentru a salva știrile ca o listă de dicționare în care fiecare dicționar este o singură știre.
- Salvați știrile într-un fișier CSV.
- Puteți arunca o privire la mai multe fluxuri rss ale site-ului de știri folosit în exemplul de mai sus. Puteți încerca să creați o versiune extinsă a exemplului de mai sus, analizând și alte fluxuri rss.
- Ești fan de cricket? Apoi acest Feed-ul rss trebuie să fie de interes! Puteți analiza acest fișier XML pentru a răzui informații despre meciurile de cricket live și îl puteți utiliza pentru a crea un notificator pe desktop!
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 în directorul nostru local. Pentru mai multe informații despre cum funcționează modulul de solicitări, urmați acest articol: Solicitări GET și POST folosind Python
Aici folosim xml.etree.ElementTree (numiți-l ET pe scurt) modul. Element Tree are două clase în acest scop - ElementTree reprezintă întregul document XML ca arbore și Element reprezintă un singur nod în acest arbore. Interacțiunile cu întregul document (citirea și scrierea în/din fișiere) se fac de obicei pe ElementTree nivel. Interacțiunile cu un singur element XML și subelementele acestuia se fac pe Element nivel. Ok, să trecem prin parseXML() function now: tree = ET.parse(xmlfile)Here we create an ElementTree obiect prin analizarea trecutului xmlfile.
root = tree.getroot()înrădăcinat() funcția returnează rădăcina lui copac ca o 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 articol element. ./canal/articol este de fapt XPath sintaxă (XPath este un limbaj pentru adresarea unor părți ale unui document XML). Aici vrem să le găsim pe toate articol nepoţii de canal copii ai rădăcină (notat cu '.') element. Puteți citi mai multe despre sintaxa XPath acceptată Aici . 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 articol elemente în care fiecare articol elementul conține o știre. Așa că creăm un gol ştiri 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'] copil.attribu este un dicționar al tuturor atributelor legate de un element. Aici ne interesează url atributul de media:conținut namespace tag. Now for all other children we simply do: news[child.tag] = child.text.encode('utf8') copil.tag conține numele elementului copil. copil.text 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 site-uri de știri . În cele din urmă, această listă este returnată.
După cum puteți vedea, datele ierarhice ale fișierului XML au fost convertite într-un fișier CSV simplu, astfel încât toate știrile să fie stocate sub forma unui tabel. Acest lucru facilitează extinderea bazei de date. De asemenea, se pot folosi datele asemănătoare JSON direct în aplicațiile lor! Aceasta este cea mai bună alternativă pentru extragerea datelor de pe site-uri web care nu oferă un API public, dar oferă unele fluxuri RSS. Toate codurile și fișierele utilizate în articolul de mai sus pot fi găsite Aici . Ce urmează?