As far as I can see, the correct URL is
http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData?$filter=month%28NEW_DATE%29%20eq%201%20and%20year%28NEW_DATE%29%20eq%202015
whereas in your code there is (no ?
after Data
)
http://data.treasury.gov/feed.svc/DailyTreasuryYieldCurveRateData$filter=month%28NEW_DATE%29%20eq%201%20and%20year%28NEW_DATE%29%20eq%202015
That's why your code currently produces the following 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>
And of course there is no atom:entry
in that error message.
Further, your XPath expression:
//atom:entry[last()]/d:BC_1YEAR
will not retrieve d:BC_1YEAR
because d:BC_1YEAR
is not an immediate child of atom:entry
. Use
//atom:entry[last()]//d:BC_1YEAR
or, even better, register the m:
prefix in the code and use
//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)
EDIT: As a response to your comment:
I want my code to work 'indefinitely' with as little maintenance as possible. I don't know what the purpose of namespaces really are and I wonder if these particular namespaces are generic and can be expected to stay that way for years to come?
I have already explained the purpose of namespaces in XML elsewhere - please look at that answer, too. Namespaces are never generic, in fact, they are the exact opposite of generic - they are supposed to be unique.
That said, there are ways to ignore namespaces. An expression like
//atom:entry[last()]//d:BC_1YEAR
Can be rewritten as
//*[local-name() = 'entry'][last()]//*[local-name() = 'BC_1YEAR']
to find elements regardless of their namespace. This would be an option if you had reason to believe the namespace URIs are going to change in the future.