The downside of Apple’s iPod/iPhone being so popular is that so many podcasts only publish iTunes links, instead of the more standard RSS/Atom feeds. And I know of OS X and Windows users who detest iTunes — imagine how Unix users feel!
Well, the feeds are still there, but hidden from plain sight — turns out, though, that if you pretend to be iTunes, you can actually trick the iTMS server into giving you the raw data. And with Python 2.6’s built-in support for Apple’s property lists, extracting the feed is a trivial matter.
#!/usr/bin/env python import plistlib import urllib2 import sys ITUNES_VER = '7.4.1' USER_AGENT = 'iTunes/' + ITUNES_VER def get_props(url): request = urllib2.Request(url) request.add_header('User-Agent', USER_AGENT) response = urllib2.urlopen(request) return plistlib.readPlistFromString(response.read()) def get_feed(url): next_url = get_props(url)['action']['url'] props = get_props(next_url) return props['items'][0]['feedURL'] if __name__ == '__main__': for url in sys.argv[1:]: print get_feed(url)
update (2010-08-27)
Apple removed one level of indirection, and the code above can be simplified. For historicity, I’m not editing the displayed code, but apply this patch, either by hand or using ‘patch’:
--- a/itms_extract.py +++ b/itms_extract.py @@ -15,8 +15,7 @@ def get_props(url): return plistlib.readPlistFromString(response.read()) def get_feed(url): - next_url = get_props(url)['action']['url'] - props = get_props(next_url) + props = get_props(url) return props['items'][0]['feedURL'] if __name__ == '__main__':
update (2011-04-05)
The latest code, for your convenience, at gist.github.com
I haven’t tried it yet, but this will be very useful to me. Cheers!
Pingback: Information Technology Governance | Fallacy Fantasy Fact
It would be great if we could teach Rhythmbox to read these kind of links using the same system…
It doesnt work anymore the next_url part in get_feed isn’t necessary anymore (at least it wasn’t when i tested it) you can just do return get_props(url)[‘items’][0][‘feedURL’] instead. Works like a charm now, thanx!
@ Meidor
Yup, discovered it myself but I forgot to update the post. Thanks for the reminder, and glad you fixed it for yourself.
This is the exception that proves Wheeler’s aphorism that all problems can be solved by another level of indirection 🙂
http://en.wikipedia.org/wiki/Abstraction_layer#cite_note-1