XML parsēšana programmā Python
Šis raksts koncentrējas uz to, kā var parsēt doto XML failu un strukturētā veidā iegūt no tā dažus noderīgus datus. XML: XML nozīmē eXtensible Markup Language. Tas bija paredzēts datu glabāšanai un transportēšanai. Tas tika izstrādāts tā, lai tas būtu lasāms gan cilvēkiem, gan mašīnlasāmiem. Tāpēc XML dizaina mērķi uzsver vienkāršību, vispārīgumu un lietojamību visā internetā. Šajā apmācībā parsējamais XML fails patiesībā ir RSS plūsma. RSS: RSS (bagātināts vietnes kopsavilkums, ko bieži sauc par ļoti vienkāršu sindikāciju) izmanto standarta tīmekļa plūsmas formātu saimi, lai publicētu bieži atjauninātu informāciju, piemēram, emuāra ierakstus, ziņu virsrakstus audiovideo. RSS ir XML formatēts vienkāršs teksts.
- Pats RSS formāts ir salīdzinoši viegli lasāms gan automatizētiem procesiem, gan cilvēkiem.
- Šajā apmācībā apstrādātais RSS ir populāras ziņu vietnes populārāko ziņu RSS plūsma. Jūs varat to pārbaudīt šeit . Mūsu mērķis ir apstrādāt šo RSS plūsmu (vai XML failu) un saglabāt to kādā citā formātā turpmākai lietošanai.
#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: - Ielādējiet RSS plūsmu no norādītā URL un saglabājiet to kā XML failu.
- Parsējiet XML failu, lai saglabātu ziņas kā vārdnīcu sarakstu, kurā katra vārdnīca ir viens ziņu vienums.
- Saglabājiet ziņas CSV failā.
- Varat apskatīt citas ziņu vietnes RSS plūsmas, kas izmantotas iepriekš minētajā piemērā. Varat mēģināt izveidot iepriekš minētā piemēra paplašinātu versiju, parsējot arī citas RSS plūsmas.
- Vai jūs esat kriketa fans? Tad šis RSS plūsmai ir jābūt jūsu interesēm! Varat parsēt šo XML failu, lai nokasītu informāciju par tiešraides kriketa spēlēm un izmantotu, lai izveidotu darbvirsmas paziņotāju.
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 mūsu vietējā direktorijā. Lai iegūtu plašāku ieskatu par pieprasījumu moduļa darbību, skatiet šo rakstu: IEGŪT un POST pieprasījumus, izmantojot Python
Šeit mēs izmantojam xml.etree.ElementTree (īsi to sauciet par ET) modulis. Šim nolūkam Element Tree ir divas klases - ElementTree attēlo visu XML dokumentu kā koku un Elements apzīmē vienu mezglu šajā kokā. Mijiedarbība ar visu dokumentu (lasīšana un rakstīšana uz/no failiem) parasti tiek veikta uz ElementTree līmenī. Mijiedarbība ar vienu XML elementu un tā apakšelementiem tiek veikta uz Elements līmenī. Labi, iesim cauri parseXML() function now: tree = ET.parse(xmlfile)Here we create an ElementTree objektu, parsējot nokārtoto xml fails.
root = tree.getroot()iesakņojies () funkcija atgriež sakni koks kā an Elements 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 vienumu elements. ./kanāls/vienums patiesībā ir XPath sintakse (XPath ir valoda XML dokumenta daļu adresēšanai). Šeit mēs vēlamies atrast visu vienumu gada mazbērni kanālu gada bērni sakne (apzīmēts ar '.') elements. Varat lasīt vairāk par atbalstīto XPath sintaksi šeit . 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 vienumu elementi, kur katrs vienumu elements satur vienu ziņu. Tātad mēs izveidojam tukšu ziņas 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'] bērns.attrib ir visu ar elementu saistīto atribūtu vārdnīca. Šeit mēs esam ieinteresēti url atribūts mediji: saturs namespace tag. Now for all other children we simply do: news[child.tag] = child.text.encode('utf8') bērns.tag satur bērna elementa nosaukumu. bērns.teksts 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 jaunumu vietnes . Beidzot šis saraksts ir atgriezts.
Kā redzat, hierarhiskā XML faila dati ir pārveidoti par vienkāršu CSV failu, lai visi ziņu stāsti tiktu saglabāti tabulas veidā. Tas atvieglo arī datu bāzes paplašināšanu. Arī JSON līdzīgus datus var izmantot tieši savās lietojumprogrammās! Šī ir labākā alternatīva datu iegūšanai no vietnēm, kas nenodrošina publisku API, bet nodrošina dažas RSS plūsmas. Visu iepriekš rakstā izmantoto kodu un failus var atrast šeit . Kas tālāk?