2012-02-02 109 views
19

我正在嘗試編寫一個與last.fm API交互的小腳本。ElementTree findall()返回空列表

我有一點ElementTree的使用經驗,但我以前使用它的方式似乎並不奏效,它反而會返回一個空的列表。
我刪除了API密鑰,因爲我不確切知道它應該是多少私有的,並給出了我在其中接收到的XML的示例。

類與API交互:

from xml.etree import ElementTree 
import urllib 
import urllib2 

class Last_fmWrapper(object): 
    def __init__(self): 
     self.last_fm_api_key = '*****************************' 
     self.api_url = 'http://ws.audioscrobbler.com/2.0/' 
    def get_now_playing(self, last_fm_user, method): 
     self.last_fm_user = last_fm_user 
     self.method = method 
     parameters = {'user':self.last_fm_user, 'api_key':self.last_fm_api_key, 'method':self.method} 
     encoded_parameters = urllib.urlencode(parameters) 
     request = urllib2.Request(self.api_url, encoded_parameters) 
     response = urllib2.urlopen(request) 
     api_results = ElementTree.parse(response).findall('track') 
     # why does api_results == []? 

    def compare_tasteometer(self): 
     pass 

    def register_user(self): 
     pass 

電話get_now_playing的Last_fmWrapper()方法:

from last_fm_wrapper import Last_fmWrapper 
last_fm = Last_fmWrapper() 
now_playing = last_fm.get_now_playing('BiriBiriRG', 'user.getRecentTracks') 
if now_playing == None: 
    print 'You not currently playing anything.' 
else: 
    print 'You are now playing {}'.format(now_playing) 

XML的樣品我收到:

<?xml version="1.0" encoding="utf-8"?> 
<lfm status="ok"> 
<recenttracks user="BiriBiriRG" page="1" perPage="10" totalPages="18406" total="184058" > 
<track> 
       <artist mbid="01809552-4f87-45b0-afff-2c6f0730a3be">Elvis Presley</artist> 
<name>Thrill Of Your Love</name> 
<streamable>1</streamable> 
<mbid></mbid> 
     <album mbid="c445fa3a-3b24-41d4-b955-b6ca560c6f7a">Love Songs</album> 
    <url>http://www.last.fm/music/Elvis+Presley/_/Thrill+Of+Your+Love</url> 
    <image size="small">http://userserve-ak.last.fm/serve/34s/69037914.png</image> 
    <image size="medium">http://userserve-ak.last.fm/serve/64s/69037914.png</image> 
    <image size="large">http://userserve-ak.last.fm/serve/126/69037914.png</image> 
    <image size="extralarge">http://userserve-ak.last.fm/serve/300x300/69037914.png</image> 
     <date uts="1328153196">2 Feb 2012, 03:26</date> 
</track> 
<track> 
       <artist mbid="efc8a006-d0c6-4a9b-8cb1-91ca770fa2b9">Colbie Caillat</artist> 
<name>Oxygen</name> 
<streamable>1</streamable> 
<mbid></mbid> 
     <album mbid="2d297b29-a215-42fe-8a8c-dc8b502903b1">Coco</album> 
    <url>http://www.last.fm/music/Colbie+Caillat/_/Oxygen</url> 
    <image size="small">http://userserve-ak.last.fm/serve/34s/69229764.png</image> 
    <image size="medium">http://userserve-ak.last.fm/serve/64s/69229764.png</image> 
    <image size="large">http://userserve-ak.last.fm/serve/126/69229764.png</image> 
    <image size="extralarge">http://userserve-ak.last.fm/serve/300x300/69229764.png</image> 
     <date uts="1328152962">2 Feb 2012, 03:22</date> 
</track> 
<track> 

回答

33

問題是findallonly searches the immediate descendants of an element if it is given a tag name。您需要爲其提供一個XPath表達式,該表達式將在其下的樹中的任意位置找到track。因此,以下應該工作,例如:

api_results = ElementTree.parse(response).findall('.//track') 
+0

謝謝!現在就像魅力一樣! – Cirno 2012-02-02 12:40:21

+0

@Cirno:很好,沒有問題:)因爲這解決了你的問題,如果你通過點擊我的✔接受答案(http://meta.stackexchange.com/a/5235)會很好。回答。 – 2012-02-02 12:45:55

+1

嗨,謝謝你的回答。我需要找到如下所示的內容:「標籤名稱中的」{http://purl.org/rss/1.0/}item「 - 」item「。忽略名稱空間。我試過:findall('.//{*} item'),但它不會工作。任何想法? 我從http://bugs.python.org/issue18304#msg194896 – Kostanos 2013-11-27 00:54:47