Java程序自动下载谷歌音乐歌词
近期写了一个android音乐播放器,但是苦于找不到可以自动下载歌词的网站。网上搜的那个已经不能用了。这时候想起可以调用百度或者谷歌的接口来搜索歌词,由于谷歌刚刚推出了谷歌音乐,于是我就想着去尝试下。
进入谷歌音乐的主页,然后随便输了首歌去搜索,跳转至歌曲搜索。发现真的有歌词,可惜歌词不是嵌套在网页里的,并且打开歌词网页的地址里包含的是歌词的id,这可这么半呢?
于是我就去搜索页面寻找歌曲的id,果然在html源代码中找到了歌曲的id,然后我就用这个id拼接在歌词网址的字符串中,最后顺利地进入了歌词页面。
不过歌词页面中的信息很少,连歌词都是从别的地方读取过来的,html源代码中也没有歌词相应的地址。还好,在页面的框架信息中我看到了歌词的地址,在浏览器输入后就可以直接下载,并且下载后的文件就是歌曲的歌词,不含其他信息。
这样就有思路了:
1.接收参数为歌曲名和歌手(这样可以准确的定位歌词文件),然后把参数拼接在查询字符串后面,进行歌词页面的查询。
2.获取歌词页面的html源代码并进行解析,获取歌曲的id
3.将歌曲的id拼接在歌词框架页面地址的后面,获取歌词框架页面的html源代码
4.解析框架页面的源代码,获取歌词下载地址。
5.下载歌词并保存至文件。
需要注意的是:
1.谷歌音乐的歌曲、歌手都不是很多,有些歌曲可能搜索不到歌词,甚至谷歌就没有收录这些歌曲。
2.谷歌服务器不稳定,歌词可能会下载失败,原因大家都懂得。
3.下载的歌词默认放在工程目录下,可以自行修改歌词位置。
4.谷歌音乐页面编码都是UTF-8的,不需要考虑乱码的问题。
PS:本程序仅仅是抛砖引玉,具体怎么使用就看大家的了。
下面上代码:
工具类
- <span style=”font-family:FangSong_GB2312;”><span style=”font-size: 14px;”></span></span><pre name=”code” class=”java”>package com.zyc.download_lrc;
- /**
- * Get lrc from google music
- * Version 1.00
- * @author zyc
- * 2012.2.2
- */
- /*
- * Step:
- * 1.Input music’s name and artist,use google music search engine
- * The url like ”http://www.google.cn/music/search?q=name+artist”
- * 2.Get music id,the id is starts with ”http://g.top100.cn/16667639/html/lyrics.html?id”
- * and id is after
- * 3.Use id to get lrc framework html,find download lrc url
- * 4.download lrc
- * 5.write lrc to file
- *
- * NOTICE:google work may abnormal,you known
- */
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileWriter;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.net.SocketTimeoutException;
- import java.net.URL;
- import java.net.URLConnection;
- public class DownloadGoogleLrcTool {
- /*music info start,but can’t get id from this,because the music has no lrc*/
- private final static String ID_HEAD_FLAG = ”<!–freemusic”;
- /*google music engine search head*/
- private final static String SEARCH_ENGINE_HEAD = ”http://www.google.cn/music/search?q=”;
- /*google music lrc by id head*/
- private final static String SEARCH_ID_URL_HEAD = ”http://www.google.cn/music/top100/lyrics?id=”;
- /*google music id flag*/
- private final static String SEARCH_ID_FLAG = ”http://g.top100.cn/16667639/html/lyrics.html?id”;
- /*google music download url flag*/
- private final static String SEARCH_LRC_DOWNLOAD_URL_FLAG = ”http://lyric.top100.cn/”;
- /*”%3D” means ”=”*/
- private final static String SEARCH_HTML_EQUAL = ”%3D”;
- private final static String END_FLAG = ”\\”;
- private final static String LRC_SUFFIX = ”.lrc”;
- private final static String LINE_END = ”\n”;
- /*google music can’t connect return code”*/
- private final static String GOOGLE_SB_RETURN_CODE = ”502″;
- /*error message,you know”*/
- private final static String GOOGLE_SB_MESSAGE = ”google抽风中…你懂的\n请稍后再试”;
- private final static String SPACE = ” ”;
- /*”%20″ means ” ”*/
- private final static String HTML_SPACE = ”%20″;
- private final static String HTML_URL_HEAD = ”http://”;
- /*id is letter and number”*/
- private final static String ID_MATCH = ”^[A-Za-z0-9]+{1}quot;;
- /*download message*/
- private final static String CANNOT_FIND_LEC_MESSAGE = ”无法找到歌词”;
- private final static String FAIL_MESSAGE = ”下载歌曲 %s-%s 歌词 失败!\n原因:”;
- private final static String SUCCESS_MESSAGE = ”下载歌曲 %s-%s 歌词 成功!\n歌词位置: %s\n”;
- private final static String DOWNLOADING_MESSAGE = ”正在下载歌曲 %s-%s 歌词…\n”;
- /*time out message*/
- private final static String DOWNLOADING_CONNECT_TIME_OUT = ”connect timed out”;
- private final static String DOWNLOADING_CONNECT_TIME_OUT_MESSAGE = ”连接超时,请检查网络配置”;
- private final static String DOWNLOADING_UNKNOWN_MESSAGE = ”未知”;
- /*set timeout = 5s*/
- private final static long CONNECT_TIME_OUT = 5000;
- /*set http proxy,if don’t use http proxy,set it false*/
- private final static boolean USE_HTTP_PROXY = true;
- private final static String FAIL_WRITE_FILE_MESSAGE = ”写入文件失败!”;
- public static void downloadLrcFromGoogle(String name,String artist){
- try {
- System.out.printf(DOWNLOADING_MESSAGE,name,artist);
- /*get lrc*/
- String lrc = downloadLrc(name,artist);
- if(lrc != null){
- /*write lrc to file*/
- String fileName = name + LRC_SUFFIX;
- File file = new File(fileName);
- writeToFile(file, lrc);
- System.out.printf(SUCCESS_MESSAGE, name,artist,file.getAbsoluteFile());
- }
- else
- System.out.println(CANNOT_FIND_LEC_MESSAGE);
- } catch (Exception e) {
- System.out.printf(FAIL_MESSAGE, name,artist);
- if(e.getMessage().contains(GOOGLE_SB_RETURN_CODE))
- System.out.println(GOOGLE_SB_MESSAGE);
- else if(e.getMessage().contains(DOWNLOADING_CONNECT_TIME_OUT)){
- System.out.println(DOWNLOADING_CONNECT_TIME_OUT_MESSAGE);
- }
- else {
- System.out.println(DOWNLOADING_UNKNOWN_MESSAGE);
- }
- //e.printStackTrace();
- }
- }
- private static void init(){
- System.setProperty(“sun.net.client.defaultConnectTimeout”, String.valueOf(CONNECT_TIME_OUT));
- if(USE_HTTP_PROXY){
- //add http proxy setting here
- }
- }
- private static String downloadLrc(String name,String artist) throws IOException,SocketTimeoutException{
- init();
- /*replace ” ” to ”%2d”*/
- name = name.replaceAll(SPACE, HTML_SPACE);
- artist = artist.replaceAll(SPACE, HTML_SPACE);
- String id = getSongId(name, artist);
- /*can’t find id return null”*/
- if(id == null || !id.matches(ID_MATCH)){
- return null;
- }
- String path = getLrcDownloadUrl(id);
- String lrc = null;
- /*if path isn’t start with ”http”//” ignore*/
- if(path.startsWith(HTML_URL_HEAD))
- lrc = doDownloadLrc(path);
- return lrc;
- }
- private static String getSongId(String name,String artist) throws IOException{
- String source = readHtml(SEARCH_ENGINE_HEAD + name + ”+” + artist);
- name = name.replaceAll(HTML_SPACE, SPACE);
- String match01 = ”\”><b>” + name + ”</b>”;
- String match02 = null;
- if(name.contains(SPACE)){
- /*set first letter upper*/
- String[] array = name.split(SPACE);
- for (int i = 0;i < array.length;i++) {
- char firstChar = array[i].charAt(0);
- if(firstChar >= ’a' && firstChar <= ’z'){
- array[i] = array[i].replace(firstChar, (char) (firstChar - 32));//set upper
- }
- }
- String newName = ”";
- for (int i = 0;i < array.length;i++) {
- if(i < array.length - 1)
- newName += array[i] + SPACE;
- else
- newName += array[i];
- }
- match02 = ”\”><b>” + newName + ”</b>”;
- }
- if(!source.contains(match01) && match02 != null && !source.contains(match02)){
- /*may other music return*/
- return null;
- }
- int first = source.indexOf(ID_HEAD_FLAG);
- if(first == -1){
- /*no music id*/
- return null;
- }
- int last = source.indexOf(ID_HEAD_FLAG,first + ID_HEAD_FLAG.length());
- if(last != -1){
- /*ignore only a music id,if have some choose first one*/
- source = source.substring(first,last);
- }
- /*find id*/
- int start = source.indexOf(SEARCH_ID_FLAG);
- int mid = source.indexOf(SEARCH_HTML_EQUAL, start);
- int end = source.indexOf(END_FLAG,mid);
- if(start == -1 || mid == -1 || end == -1){
- //can’t find id
- return null;
- }
- String id = source.substring(mid + HTML_SPACE.length(), end);
- return id;
- }
- private static String getLrcDownloadUrl(String id) throws IOException{
- /*set music lrc html url with id*/
- String source = readHtml(SEARCH_ID_URL_HEAD + id);
- int start = source.indexOf(SEARCH_LRC_DOWNLOAD_URL_FLAG);
- int end = source.indexOf(LRC_SUFFIX,start);
- String urlString = source.substring(start, end + LRC_SUFFIX.length());
- return urlString;
- }
- private static String doDownloadLrc(String path) throws IOException{
- /*download lrc*/
- return readHtml(path);
- }
- private static String readHtml(String urlPath) throws IOException{
- /*use google music search engine*/
- URL url = new URL(urlPath);
- /*connect and get html */
- URLConnection conn = url.openConnection();
- BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
- String line = null;
- StringBuilder stringBuilder = new StringBuilder();
- while ((line = reader.readLine()) != null) {
- stringBuilder.append(line + LINE_END);
- }
- return stringBuilder.toString();
- }
- private static void writeToFile(File file,String buffer) throws IOException{
- /*write to file,file name is music’s name + ”.lrc”*/
- FileWriter writer = new FileWriter(file, false);
- try {
- writer.write(buffer);
- } catch (Exception e) {
- System.out.println(FAIL_WRITE_FILE_MESSAGE);
- }finally{
- writer.close();
- }
- }
- }
测试类
- <span style=”font-family:FangSong_GB2312;”><span style=”font-size: 14px;”></span></span><pre name=”code” class=”java”>package com.zyc.download_lrc;
- public class DownloadTest {
- public static void main(String[] args) {
- //only for test
- String name = ”决战斗室”;
- String artist = ”潘玮柏”;
- downloadMusicLrc(name, artist);
- }
- static void downloadMusicLrc(String name,String artist){
- DownloadGoogleLrcTool.downloadLrcFromGoogle(name, artist);
- }
- }
测试结果:
正在下载歌曲 决战斗室-潘玮柏 歌词…
下载歌曲 决战斗室-潘玮柏 歌词 成功!
歌词位置: /project/DownLoadLrc/决战斗室.lrc
歌词如下:
[ti:决战斗室]
[ar:潘玮柏]
[al:高手]
[00:05.00]
[01:20.44][00:16.69]克制不住 心跳加速
[01:22.27][00:18.67]太兴奋追求战斗我才满足
[01:24.25][00:20.47]角落处 全神贯注
[01:26.25][00:22.57]眼神冰冷像只危险老虎
[01:28.23][00:24.58]拳头蹦带 无法束缚
[01:30.25][00:26.55]脉膊跳动的强度快忍不住
[01:32.22][00:28.51]灯在闪 人群在喊
[01:34.19][00:30.48]抬起头我完全不屑一顾
[01:36.21][00:32.60]Noboby gonna stop me
[01:38.21][00:34.57]沉默中 聆听自己
[01:40.07][00:36.54]Noboby gonna front me
[01:42.23][00:38.51]相信自己 绝不会逃避
[01:44.25][00:40.55]Noboby gonna touch me
[01:46.19][00:42.48]呐喊声全场淹没
[01:48.12][00:44.41]推开门 走出自我
[01:50.06][00:46.22]This is my life my soul
[02:44.39][02:28.08][01:52.15][00:48.47]紧握灵魂的手
[02:45.75][02:29.93][01:54.03][00:50.35]最后一刻战斗
[02:47.86][02:31.96][01:56.10][00:52.38]黑暗恐惧之中
[02:50.61][02:33.71][01:57.84][00:54.19]决战斗室只剩你我
[02:51.86][02:35.86][02:00.09][00:56.38]倒数的计时钟
[02:53.77][02:37.90][02:02.00][00:58.30]胜利才终结转动
[02:57.37][02:41.51][02:05.59][01:01.84]我闭上眼我站在斗室中
[02:59.29][02:43.35][02:07.50][01:03.94]只剩下Oh oh
然后就可以放进手机同步播放了!
搞定!!!

Leave a Reply