小西0 2013-04-20
现在听歌用百度随心听,感觉里面的歌还不错,把喜欢的歌都存到百度云音乐中去了,可是到想把百度云音乐中的歌曲下载到本地时,发现它竟然没有提供批量下载的功能,于是自己动手写代码来实现批量下载歌曲。
package pml; import java.io.*; import java.net.*; import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; import net.sf.json.JSONArray; import net.sf.json.JSONObject; public class BaiduCloundMusic { public static void main(String[] args) throws Exception { BaiduCloundMusic bcm = new BaiduCloundMusic(); bcm.login("username", "password"); bcm.downloadAll(); } private String cookieValue = ""; private String downloadDirectory = "d:/baidumusic"; /** * 登陆百度,其他方法调用之前需要先登陆 * @param username * @param password */ public void login(String username, String password){ try { URL url=new URL("http://www.baidu.com/"); HttpURLConnection httpUrlConnection=(HttpURLConnection)url.openConnection(); httpUrlConnection.setRequestMethod("GET"); String cookie1=httpUrlConnection.getHeaderField("Set-Cookie"); //System.out.println("cookie1:"+cookie1); cookie1 = cookie1.substring(0,45); url=new URL("https://passport.baidu.com/v2/api/?getapi&class=login&tpl=mn&tangram=true"); httpUrlConnection=(HttpURLConnection)url.openConnection(); httpUrlConnection.setRequestMethod("GET"); httpUrlConnection.setRequestProperty("Cookie", cookie1); //httpUrlConnection.connect(); String cookie2 = httpUrlConnection.getHeaderField("Set-Cookie"); System.out.println("cookie2:"+cookie2); cookie2 = cookie2.substring(0,11); String response = getResponse(httpUrlConnection.getInputStream()); //System.out.println(response); Pattern pattern = Pattern.compile("token='(\\w+)'"); Matcher matcher = pattern.matcher(response); matcher.find(); String token = matcher.group(1); url=new URL("https://passport.baidu.com/v2/api/?login"); httpUrlConnection=(HttpURLConnection)url.openConnection(); httpUrlConnection.setRequestMethod("POST"); //System.out.println(cookie1+"; "+cookie2); httpUrlConnection.setRequestProperty("Cookie", cookie1+"; "+cookie2); httpUrlConnection.setDoOutput(true); //System.out.println(token); String querystring = "loginType=1&tpl=mn&token="+token+"&username="+username+ "&password="+password+"&mem_pass=on"; httpUrlConnection.getOutputStream().write(querystring.getBytes()); httpUrlConnection.getOutputStream().flush(); httpUrlConnection.getOutputStream().close(); response = getResponse(httpUrlConnection.getInputStream()); //System.out.println(response); //String cookie3=httpUrlConnection.getHeaderField("Set-Cookie"); //System.out.println("cookie3:"+cookie3); //获取登陆后的cookie Map<String, List<String>> hfs=httpUrlConnection.getHeaderFields(); List<String> loginCookies = hfs.get("Set-Cookie"); for(String cookie:loginCookies){ cookieValue += cookie.substring(0,cookie.indexOf(";")+1); } } catch (Exception e) { e.printStackTrace(); } } /** * 获得歌曲列表 * @return [{ngId:'',songName:'',artistName:''},...] */ public List<JSONObject> getSongList(){ List<JSONObject> songList = new ArrayList<JSONObject>(); //解析歌曲列表 String link = "http://yinyueyun.baidu.com/data/cloud/collection?type=song&start=0&size=200"; String response = getResponse(link); JSONArray songIds = JSONObject.fromObject(response).getJSONObject("data").getJSONArray("songList"); for(int i=0;i<songIds.size();i++){ JSONObject songInfo = getSongInfo(songIds.getJSONObject(i).getString("id")); songList.add(songInfo); } return songList; } public void downloadAll(){ List<JSONObject> songList = getSongList(); for(int i=0;i<songList.size();i++){ String songId = songList.get(i).getString("songId"); download(songId); } } public File download(String songId){ try { String maxRate = getMaxRate(songId); JSONObject songInfo = getSongInfo(songId); //以歌手名字+歌曲名称组成文件名,格式:歌手 - 歌曲名称 String filename = songInfo.getString("artistName")+" - "+songInfo.getString("songName"); String link = "http://yinyueyun.baidu.com/data/cloud/downloadsongfile?songIds="+songId+"&rate="+maxRate; URL urlObject=new URL(link); HttpURLConnection httpUrlConnection=(HttpURLConnection)urlObject.openConnection(); httpUrlConnection.setRequestMethod("GET"); httpUrlConnection.setDoOutput(true); httpUrlConnection.setRequestProperty("Cookie", cookieValue); String disposition = httpUrlConnection.getHeaderField("Content-Disposition"); disposition = disposition.replaceAll("\"", ""); //此转码经测试发现有些是UTF-8编码,有些是GBK编码,所以文件名采用另外方式获得 //disposition = new String(disposition.getBytes("iso-8859-1"),"UTF-8"); //根据disposition中信息确定歌曲格式 String suffix = disposition.substring(disposition.lastIndexOf(".")); //System.out.println(disposition); InputStream inputStream= httpUrlConnection.getInputStream(); File file = new File(downloadDirectory+"/"+filename+suffix); FileOutputStream fos = new FileOutputStream(file); byte[] buf = new byte[4096]; int read=0; while((read=inputStream.read(buf)) > 0){ fos.write(buf,0,read); } fos.flush(); fos.close(); inputStream.close(); //System.out.println("完成<"+file.getName()+">歌曲下载!"); return file; }catch (Exception e) { e.printStackTrace(); return null; } } /** * 获得歌曲的最大码率 * @param songId * @return */ public String getMaxRate(String songId){ String link = "http://yinyueyun.baidu.com/data/cloud/download?songIds="+songId; String response = getResponse(link); JSONObject rates = JSONObject.fromObject(response).getJSONObject("data").getJSONObject("data"); String maxRate = (rates.getString("320").length()>0?"320":(rates.getString("192").length()>0?"192":"128")); return maxRate; } /** * 获得歌曲详细信息 * @param songId * @return {songId:'',songName:'',artistName:''} */ public JSONObject getSongInfo(String songId){ String link = "http://yinyueyun.baidu.com/data/cloud/songinfo?songIds="+songId; String response = getResponse(link); JSONObject songInfo = JSONObject.fromObject(response).getJSONObject("data").getJSONArray("songList").getJSONObject(0); return songInfo; } private String getResponse(String link){ try { URL urlObject=new URL(link); HttpURLConnection httpUrlConnection=(HttpURLConnection)urlObject.openConnection(); httpUrlConnection.setRequestMethod("GET"); httpUrlConnection.setDoOutput(true); httpUrlConnection.setRequestProperty("Cookie", cookieValue); return getResponse(httpUrlConnection.getInputStream()); }catch (Exception e) { e.printStackTrace(); } return ""; } private String getResponse(InputStream in){ StringBuilder response=new StringBuilder(); try{ BufferedReader rd = new BufferedReader(new InputStreamReader(in)); char[] buf = new char[1024]; int read=0; while((read=rd.read(buf)) > 0){ response.append(buf,0,read); } rd.close(); in.close(); }catch (Exception e) { e.printStackTrace(); } return response.toString(); } }
id=3&hmsr=%E5%BC%80%E5%8F%91%E8%80%85-AI%E5%AD%A6%E4%B9%A0%E8%B7%AF%E7%BA%BF&hmpl=&hmcu=&hmkw=&hmci=