我试图抓住BC_1YEAR和NEW_DATE的内容,查看this data中的最后一个条目。
这是我的Google App Engine的Python代码:
import lxml.etree
from google.appengine.api import urlfetch
def foo():
url = 'http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData$filter=month(NEW_DATE)%20eq%201%20and%20year(NEW_DATE)%20eq%202015'
response = urlfetch.fetch(url)
tree = lxml.etree.fromstring(response.content)
nsmap = {'atom': 'http://www.w3.org/2005/Atom',
'd': 'http://schemas.microsoft.com/ado/2007/08/dataservices'}
myData = tree.xpath("//atom:entry[last()]/d:BC_1YEAR", namespaces=nsmap)
但myData是一个空列表,而今天的数据应该是0.2。我已经花了好几个小时才开始工作,所以任何帮助都会非常感激。我假设NEW_DATE的工作方式类似。
答案 0 :(得分:1)
据我所知,正确的网址是
http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData?$filter=month%28NEW_DATE%29%20eq%201%20and%20year%28NEW_DATE%29%20eq%202015
而在您的代码中,?
之后没有Data
http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData$filter=month%28NEW_DATE%29%20eq%201%20and%20year%28NEW_DATE%29%20eq%202015
这就是您的代码当前生成以下XML的原因:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<code></code>
<message xml:lang="en-US">Resource not found for the segment 'DailyTreasuryYieldCurveRateData$filter=month'.</message>
</error>
当然,该错误消息中没有atom:entry
。
此外,您的XPath表达式:
//atom:entry[last()]/d:BC_1YEAR
不会检索d:BC_1YEAR
,因为d:BC_1YEAR
不是atom:entry
的直接子项。使用
//atom:entry[last()]//d:BC_1YEAR
或者更好的是,在代码中注册m:
前缀并使用
//atom:entry[last()]/atom:content/m:properties/d:BC_1YEAR
import lxml.etree
from google.appengine.api import urlfetch
def foo():
url = 'http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData?$filter=month%28NEW_DATE%29%20eq%201%20and%20year%28NEW_DATE%29%20eq%202015'
response = urlfetch.fetch(url)
tree = lxml.etree.fromstring(response.content)
nsmap = {'atom': 'http://www.w3.org/2005/Atom',
'd': 'http://schemas.microsoft.com/ado/2007/08/dataservices',
'm': 'http://schemas.microsoft.com/ado/2007/08/dataservices/metadata'}
myData = tree.xpath("//atom:entry[last()]/atom:content/m:properties/d:BC_1YEAR", namespaces=nsmap)
编辑:作为对您评论的回复:
我希望我的代码可以无限期地使用&#39;尽可能少的维护。我不知道命名空间的目的是什么,我想知道这些特定的命名空间是否是通用的,并且可以预期在未来几年保持这种状态?
我已经explained the purpose of namespaces in XML elsewhere了 - 请看一下这个答案。命名空间永远不是通用的,事实上,它们与泛型完全相反 - 它们应该是唯一的。
也就是说,有一些方法可以忽略命名空间。像
这样的表达式//atom:entry[last()]//d:BC_1YEAR
可以改写为
//*[local-name() = 'entry'][last()]//*[local-name() = 'BC_1YEAR']
查找元素而不管其名称空间。如果您有理由相信命名空间URI将来会发生变化,那么这将是一个选项。