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

 

偶尔关注朋友的主页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每天都会变,所以现在打开的话链接已经过期了,要实时解析才能用

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

  1. package  test;
  2.  
  3. import  java.io.IOException;
  4. import  java.io.UnsupportedEncodingException;
  5. import  java.net.URL;
  6. import  java.net.URLDecoder;
  7. import  javax.xml.parsers.DocumentBuilder;
  8. import  javax.xml.parsers.DocumentBuilderFactory;
  9. import  javax.xml.parsers.ParserConfigurationException;
  10.  
  11. import  org.w3c.dom.Document;
  12. import  org.w3c.dom.Node;
  13. import  org.w3c.dom.NodeList;
  14. import  org.xml.sax.SAXException;
  15.  
  16.  
  17. public   class  XiamiDecode {
  18.  
  19. public   static   void  main(String[]  args ) {
  20. XiamiDecode  xd  =  new  XiamiDecode();
  21. String  deURL  =  xd .getLocation( "http://www.xiami.com/song/playlist/id/20550/" );
  22. try  {
  23. String  finallyURL  = URLDecoder. decode ( deURL "utf-8" );
  24. System. out .println( finallyURL .replace( "^" , "0"  ));
  25. catch  (UnsupportedEncodingException  e ) {
  26.  
  27. e .printStackTrace();
  28. }
  29.  
  30. }
  31.  
  32.  
  33. private  String getLocation(String  s ){
  34. DocumentBuilderFactory  dbf  = DocumentBuilderFactory. newInstance ();
  35. try  {
  36. DocumentBuilder  db  =  dbf .newDocumentBuilder();
  37. URL  url  =  new  URL( s );
  38.             Document  d  =  db .parse( url .openStream());
  39.             NodeList  trackList  =  d .getElementsByTagName_r( "trackList" );      
  40.             Node  track  =  trackList .item(0).getFirstChild();
  41.             System. out .println( track .getNodeName());
  42.             NodeList  nl  =  track .getChildNodes();
  43.  
  44.             String  s2  =  nl .item(24).getTextContent();
  45.             System. out .println( s2 );
  46.  
  47.              int   heigth  = Integer. valueOf ( s2 .substring(0, 1));  
  48.             String  s3  =  s2 .substring(1);
  49.              int   width  =  s3 .length()/  heigth ;
  50.              int   remainder  =  s3 .length()%  heigth ;
  51.             String[]  urlSeparate  =  new  String[ heigth ];
  52.             
  53.              for  ( int   i  = 0;  i  <  urlSeparate . length i ++) {
  54.              if ( remainder  > 0 ){
  55.              urlSeparate [ i ] =  s3 .substring(0, width  +1  );
  56.              remainder --;
  57.              s3  =  s3 .substring( width + 1);
  58.              } else {
  59.              urlSeparate [ i ] =  s3 .substring(0, width   );
  60.              s3  =  s3 .substring( width );
  61.              }
  62.             
  63. System. out .println( urlSeparate [ i ]);
  64. }
  65.             String  location  =  "" ;
  66.              for  ( int   i  = 0;  i  <  urlSeparate [0].length();  i ++) {
  67. for  ( int   j  = 0;  j  <  urlSeparate . length j ++) {
  68. if ( urlSeparate [ j ].length() < urlSeparate [0].length() &&  i ==  urlSeparate [0].length() -1){
  69. continue ;
  70. } else {
  71. location  +=  urlSeparate [ j ].substring( i i +1);
  72. }
  73. }
  74. }
  75.             System. out .println( location );
  76.            
  77.              return   location ;
  78.  
  79. catch  (ParserConfigurationException  e ) {
  80. //  TODO  Auto-generated catch block
  81. e .printStackTrace();
  82. } catch  (SAXException | IOException  e ) {
  83. e .printStackTrace();
  84. }
  85. return   "fail" ;
  86. }
  87.  
  88. }

 

 

你可能感兴趣的:(Java)