您的位置:首页 > 编程语言 > Java开发

Java解析虾米音乐的真实下载地址

2014-12-23 10:52 459 查看
 

偶尔关注朋友的主页http://caiweiming.com ,他有一篇文章《用PHP解析虾米音乐的真实地址

 

原理是虾米音乐每首歌都对应一个xml文件,根据歌的id访问相应地址就会获取一个xml的输入流

 

http://www.xiami.com/song/3074953?spm=a1z1s.3521865.23309997.2.m0RY1x

这是lady gaga's poke
face的播放地址,这首歌的id号是3074953 ,访问http://www.xiami.com/song/playlist/id/3074953就会返回一个xml的输入流;

解析xml的location节点就能获得真实下载地址;

 

如何解密location的乱码?我程序就不写注释了,大概可以这样理解,举例如下

 

location字符串为6hAFlm%'27233t%�a1e195-t%mei2212F43_%h353b63b42Ent25..FF393l3_DE351521%-upF.xc8422X.Fk83e%�75%l%%fio27F9536mae2a455a32E5l32iam182%E_6puy1b1EE2-1%E

 

有人说这是“凯撒数列”,我不懂凯撒数列是什么,按我朋友的说法就是这个字符串的第一个字符是6,所以字符串需分为6行,去掉第一个字符后,字符串的长度为155,所前5行行为26个字符,最后一行为25个字符,分割字符串效果如下

hAFlm%'27233t%�a1e195-

t%mei2212F43_%h353b63b42En

t25..FF393l3_DE351521%-u

pF.xc8422X.Fk83e%�75%l

%%fio27F9536mae2a455a32E5l

32iam182%E_6puy1b1EE2-1%E

 

如上图,从上往下一个一个读字符串,将其拼接起来,就成了可以decode的字符串,拼接后的效果为
http://m5.file.xiami.com/821/47821/272329/3^74953_2338663_l.mp3?auth_key=821^3abc33e41db5^a61^135ba2eb293-14172192^^-^-null
decode后的效果就是下载地址http://m5.file.xiami.com/608/608/2651/20550_15745372_l.mp3?auth_key=370711e4597e3c2d6426e98f1af3507b-1417219200-0-null

打开这个地址就能下载音乐啦

需要注意,auth_key每天都会变,所以现在打开的话链接已经过期了,要实时解析才能用

//以下是源码,不写注释了哦

package test;

 

import java.io.IOException;

import java.io.UnsupportedEncodingException;

import java.net.URL;

import java.net.URLDecoder;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

 

import org.w3c.dom.Document;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;<
4000
/span>

import org.xml.sax.SAXException;

 

 

public class XiamiDecode {

 

public static void main(String[] args) {

XiamiDecode xd = new XiamiDecode();

String deURL = xd.getLocation("http://www.xiami.com/song/playlist/id/20550/");

try {

String finallyURL = URLDecoder.decode(deURL, "utf-8");

System.out.println(finallyURL.replace("^","0" ));

} catch (UnsupportedEncodingException e) {

 

e.printStackTrace();

}

 

}

 

 

private String getLocation(String s){

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

try {

DocumentBuilder db = dbf.newDocumentBuilder();

URL url = new URL(s);

            Document d = db.parse(url.openStream());

            NodeList trackList = d.getElementsByTagName_r("trackList");     

            Node track = trackList.item(0).getFirstChild();

            System.out.println(track.getNodeName());

            NodeList nl = track.getChildNodes();

 

            String s2 = nl.item(24).getTextContent();

            System.out.println(s2);

 

            int heigth = Integer.valueOf(s2.substring(0, 1));  

            String s3 = s2.substring(1);

            int width = s3.length()/ heigth;

            int remainder = s3.length()% heigth;

            String[] urlSeparate = new String[heigth];

            

      
da47
      for (int i = 0; i < urlSeparate.length; i++) {

            

if(remainder > 0 ){

            

urlSeparate[i] = s3.substring(0,width +1  );

            

remainder--;

            

s3 = s3.substring(width+ 1);

            

}else{

            

urlSeparate[i] = s3.substring(0,width  );

            

s3 = s3.substring(width);

            

}

            

System.out.println(urlSeparate[i]);

}

            String location = "";

            for (int i = 0; i < urlSeparate[0].length(); i++) {

for (int j = 0; j < urlSeparate.length; j++) {

if(urlSeparate[j].length() <
urlSeparate[0].length() && i== urlSeparate[0].length() -1){

continue;

}else{

location += urlSeparate[j].substring(i, i+1);

}

}

}

            System.out.println(location);

           

            return location;

 

} catch (ParserConfigurationException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}catch (SAXException | IOException e) {

e.printStackTrace();

}

return "fail";

}

 

}

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: