A constant rat race
Honestly, I don't even use hypem.com anymore since my music taste has changed, however I am constantly trying to keep my hypem chrome extension and python download script up to date with the changes to the site. People have been overall extremely generous in their compliments which is why I keep updating the script.
Although I may not use the site anymore, I am finding their constant attempts to thwart similar extensions interesting and have enjoyed the constant rate race. I've documented on my blog already several of their numerous attempts to thwart similar projects and looks like they released their latest incarnation. I hope this post will serve those who are attempting to enjoy their music beyond the confines of the site helpful.
So, What's Changed?
Previously, the link to the mp3 file was very easy to generate and scrape from their HTML page. Every song use to contain it's unique identifiers right in the 'div' element of that song. One simply had to parse out the 'key' and 'id' and construct a URL to http://hypem.com/serve/play/id/key.mp3 and your content was served on a platter. They've now added a few more tricks to their sleeve but it's still trivial getting access to the mp3.
- Firstly, they've moved where the 'key' is stored for each song. They've embedded the 'keys' of the current page in a 'script' object on the site. The interior of the script object is simply JSON.
- Secondly, they've changed the whole request mechanism for serving songs. Before as I mentioned, the /serve/play url immediately served up the Mp3. This is no longer the case. There is now an intermediate request which returns some JSON data and then finally the URL to the Mp3 is retrieved and served!
- Thirdly, this hasn't changed but don't forget about setting the cookie! Hypemachine checks for a AUTH cookie and without it will not authorize your get request for the song data! Simply store the cookie when you retrieve the HTML and use the same one when you make further requests. Voila!
Example
import urllib2
import urllib
from time import time
data = {'ax':1, 'ts':time()}
data_encoded = urllib.urlencode(data)
complete_url = "http://hypem.com/track/1q7nf?{}".format(data_encoded)
request = urllib2.Request(complete_url)
response = urllib2.urlopen(request)
html = response.read()
html_file = open("hype.html", "w")
html_file.write(html)
html_file.close()
After the page loads, they read the JSON data into a javascript variable and remove the script tag from the HTML body. So you won't be able to inspect a current page and find the code
Relevant Code from hype_functions_min.js
var req_url = '/serve/source/' + window.playList['tracks'][track].id + '/' + window.playList['tracks'][track].key;
var source_data;
var r = $.ajax({url: req_url,data: req_data,type: 'get',async: false,cache: false,dataType: 'json',error: function() {
log('playTrack /source/ request FAILED');
return false;
}});
try {
response = jQuery.parseJSON(r.responseText);
} catch (err) {
log("FAILED to parse JSON data");
return false;
}