I have been using pylast.py to retrieve various types of information about artists and events from Last.fm.

However, pylast doesn't have any functions to retrieve venue information from the event. In particular, if you look at the XML for event.getInfo, I want to retireve the location of the venue:

http://www.last.fm/api/show/event.getInfo

<venue> 
<id>8783057</id> 
<name>Ryman Auditorium</name> 
<location> 
  <city>Nashville</city> 
  <country>United States</country> 
  <street>116 Fifth Avenue North</street> 
  <postalcode>37219</postalcode> 
  <geo:point> 
     <geo:lat>36.16148</geo:lat> 
     <geo:long>-86.777959</geo:long> 
  </geo:point> 
</location> 
<url>http://www.last.fm/venue/8783057</url> 
</venue> 

Now, pylast has a method called get_venue under the event object, but it doesn't reuturn any of the location data shown above...

Is there any way to get the location data through pylast?

有帮助吗?

解决方案

Pylast hasn't been updated in a few years, but this is now possible in my fork:

artist = network.get_artist("Skinny Puppy")
event = artist.get_upcoming_events()[0]
venue = event.get_venue()
print venue.info

Prints:

{u'website': u'http://www.clubmayan.com', u'name': u'Mayan Theatre', u'url': u'http://www.last.fm/venue/8901088+Mayan+Theatre', u'image': u'http://userserve-ak.last.fm/serve/500/14221419/Mayan+Theatre+outside.jpg', u'phonenumber': u'213-746-4287', u'location': {u'postalcode': u'CA 90015', u'city': u'Los Angeles', u'geo:point': {u'geo:long': u'-118.259068', u'geo:lat': u'34.040729'}, u'street': u'1038 S. Hill St', u'country': u'United States'}, u'id': u'8901088'}

And:

print venue.location

Prints:

{u'postalcode': u'CA 90015', u'city': u'Los Angeles', u'geo:point': {u'geo:long': u'-118.259068', u'geo:lat': u'34.040729'}, u'street': u'1038 S. Hill St', u'country': u'United States'}

And:

print venue.id, venue.name

Prints:

8901088, u'Mayan Theatre'

其他提示

This looks like a limitation in pylast. If you look at the source, pylast always assumes it can stash just the ID for any sub-object, and then retrieve the rest of the info by using a getInfo service call. So, when you call event.get_venue(), that's what it does…

But in this case, it doesn't work. As you can see from the API docs, there is no venue.getInfo. Hence this comment in the pylast code:

# TODO: waiting for a venue.getInfo web service to use.

So, you will need to do one of three things:

  • Bug last.fm to add this missing method.
  • Substantially rewrite all of pylast so it stores the original XML retrieved for an object instead of just the ID, or at least so that it does so in the case of Venue.
  • Hack up the Event class to treat location as part of an event instead of part of its venue.

The last one seems like the easiest by far. However, you do have to decide how to represent a location.

Here's a quick&dirty hack that represents a location as a dict of all of its non-empty plain-text nodes, and monkey patches code to fetch it into the Event object:

def get_location(self):
    """Returns the location of the venue where the event is held."""
    doc = self._request("event.getInfo", True)
    loc = doc.getElementsByTagName("location")[0]
    return {node.nodeName: child.data
            for node in loc.childNodes
            for child in node.childNodes
            if child.nodeType == child.TEXT_NODE and child.data.strip()}        
pylast.Event.get_location = get_location

Now, code like this:

artist = network.get_artist("Skinny Puppy")
event = artist.get_upcoming_events()[0]
print event.get_location()

… should print something like this:

{'city': 'Santa Ana, CA', 'postalcode': '92704', 
 'street': '3503 S. Harbor Blvd.', 'country': 'United States'}

Not exactly beautiful, but it should serve as a useful hack until the real functionality is there.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top