2013-10-13 3 views
2

Я ищу для анализа через xml- http://charts.realclearpolitics.com/charts/1044.xml. Я хочу получить результат в кадре данных с тремя столбцами: Date, Approve, Disapprove. Файл xml является динамическим в том смысле, что каждый день добавляется новая дата, поэтому код должен учитывать это. Я внедрил решение, которое является статическим, то есть мне нужно, чтобы циклы выдавали числа строк тега значения. Я хотел бы узнать, как реализовать его динамически.Проанализируйте xml в python

import numpy as np 
import pandas as pd 
import requests 
from pattern import web 

xml = requests.get('http://charts.realclearpolitics.com/charts/1044.xml').text 
dom = web.Element(xml) 
values = dom.by_tag('value') 

date = [] 
approve = [] 
disapprove = [] 

values = dom.by_tag('value') 
#The last range number below is 1720 instead of 1727 as last 6 values of Approve & Disapprove tag are blank. 
for i in range(0,1720): 
    date.append(pd.to_datetime(values[i].content)) 

#The last range number below is 3447 instead of 3454 as last 6 values are blank. Including till 3454 will give error while converting to float. 
for i in range(1727,3447): 
    a = float(values[i].content) 
    approve.append(a) 

#The last range number below is 5174 instead of 5181 as last 6 values are blank. 
for i in range(3454,5174): 
    a = float(values[i].content) 
    disapprove.append(a) 

finalresult = pd.DataFrame({'date': date, 'Approve': approve, 'Disapprove': disapprove}) 
finalresult 
+1

LXML имеет поддержку XPATH, который, кажется, что вы хотите. Затем вы можете просто получить элементы с помощью команды xpath, независимо от того, сколько из них есть. –

ответ

2

Вот один из способов сделать это с lxml и XPath:

from lxml import etree 
import pandas as pd 

tree = etree.parse("http://charts.realclearpolitics.com/charts/1044.xml") 

date = [s.text for s in tree.xpath("series/value")] 
approve = [float(s.text) if s.text else 0.0 
      for s in tree.xpath("graphs/graph[@title='Approve']/value")] 
disapprove = [float(s.text) if s.text else 0.0 
       for s in tree.xpath("graphs/graph[@title='Disapprove']/value")] 

assert len(date) == len(approve) == len(disapprove) 

finalresult = pd.DataFrame({'Date': date, 'Approve': approve, 'Disapprove': disapprove}) 
print finalresult 

Выход:

<class 'pandas.core.frame.DataFrame'> 
Int64Index: 1727 entries, 0 to 1726 
Data columns (total 3 columns): 
Date   1727 non-null values 
Approve  1727 non-null values 
Disapprove 1727 non-null values 
dtypes: float64(2), object(1) 
+0

Спасибо за код. Он хорошо разбирается. Также это имеет 1720 ненулевых значений. Но он содержит значения 7 «Нет» в конце, что делает работу как finalresult.Approve.sum() невозможно? – PronojitS

+0

Я обновил ответ. – mzjn

Смежные вопросы