MP3网站的歌曲都采用了不同的加密方法,直接从页面的源文件中是找不到其 MP3的网址的。以下有两个public class都可独立运行,只要将其构造方法更名为main方法就可以了,同时还需要在给出的JAVA源代码中找到“//播放或下载代码...”这一行,将 其改为“Thread.sleep(1000)"延时,否则同一IP频繁的连接会遭服务器拒绝或引发服务器的防恶意搜索保护。

 

1.获取百度新歌MP3真实地址

  百度新歌的网址是http://xinge.baidu.com/,打开该页面后用查看源文件,搜索“{sid:”,会看到这样的文本:

http://xinge.baidu.com/源文件片断

{sid:'468aecfeaabbd9467fb939a2e80da58a.mp3',al:'今 生无缘',ti:'一天爱一点',si:'易欣 孙莺',cp:'华友金信子 ',da:'2010-08-03',cv:'38d9e957d5bdfb788989f1eb12239d8f.jpg',lrc:'b118977f14893a70ab4652031dd1633d.txt',dl:'511',tl:'281394',ico:0}

其中:“sid:”后面是歌曲连接、“al:”后是唱片集、“ti:”后面是歌曲标题、“si:”后面是歌手。

  • 读取“sid:”后面用一对单引号括起来的字符串,在前面加上 http://xinge.baidu.com/wgns/url/构成歌曲的链接,例如:http://xinge.baidu.com/wgns /url/468aecfeaabbd9467fb939a2e80da58a.mp3,这个链接是用于打开试听窗口的。
  • 试听窗口查看不到源文件,那就编程打开这个歌曲链接的网址并解析其源文件。在用程序接收到的源文件只有一行,在这一行字符串前面加上http://xinge.baidu.com就是MP3的真实网址了,这个网址可用于播放或下载MP3。

源代码如下:

Java代码

1. /*
2.  * XingeBaidu.java - 获取'百度新歌'的MP3真实网址
3.  */
4. package
5.     
6. import
7. import
8. import
9. import
10. import
11.     
12. public   class
13. public
14.          String strLine;   
15. int
16. "连接到百度新歌\n"
17.     
18. try
19. new  URL( "http://xinge.baidu.com/"
20.              HttpURLConnection objHttp = (HttpURLConnection) url.openConnection();   
21. "User-Agent" ,  "mozilla/5.0"
22. "Connection" ,  "Keep-Alive"
23.              InputStream objIS = objHttp.getInputStream();   
24. new  BufferedReader( new
25.     
26. while  ((strLine = objReader.readLine()) !=  null
27. if  ((beginIndex = strLine.indexOf( "{sid:" )) != - 1
28. if  ((idx = strLine.indexOf( "al:" )) != - 1
29. "',ti" )) != - 1
30. 4
31. "[唱片集:%s]  " ,strLine.substring(idx+ 4
32. if  ((idx = strLine.indexOf( "ti:" )) != - 1
33. "',si" )) != - 1
34. 4
35. "%s" , strLine.substring(idx +  4
36. if  ((idx = strLine.indexOf( "si:" )) != - 1
37. "',cp" )) != - 1
38. 4
39. "  [歌手:%s]" ,strLine.substring(idx+ 4
40. "\n"
41.     
42. if  ((endIndex = strLine.indexOf( ".mp3" )) != - 1
43. 6 , endIndex +  4
44. "http://xinge.baidu.com/wgns/url/"
45.                      }   
46.                  }   
47.              }   
48. catch
49. // e.printStackTrace();
50.          }   
51.      }   
52.     
53. private   void  getMP3URL(String surl)  throws
54.          String strLine;   
55. new
56.          HttpURLConnection objHttp = (HttpURLConnection) url.openConnection();   
57. "User-Agent" ,  "mozilla/5.0"
58.     
59.          InputStream objIS = objHttp.getInputStream();   
60. new  BufferedReader( new
61.     
62. if  ((strLine = objReader.readLine()) !=  null
63. "http://xinge.baidu.com"
64. //打印查找到的MP3的真实网址
65. //播放或下载的代码...
66.          }   
67.          objHttp.disconnect();   
68. null
69.          objReader.close();   
70. null
71. null
72.      }   
73.  }


/*
 * XingeBaidu.java - 获取'百度新歌'的MP3真实网址
 */
package jmp123.player;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.HttpURLConnection;

public class XingeBaidu {
	public XingeBaidu() {
		String strLine;
		int beginIndex, endIndex, idx;
		System.out.println("连接到百度新歌\n");

		try {
			URL url = new URL("http://xinge.baidu.com/");
			HttpURLConnection objHttp = (HttpURLConnection) url.openConnection();
			objHttp.setRequestProperty("User-Agent", "mozilla/5.0");
			objHttp.setRequestProperty("Connection", "Keep-Alive");
			InputStream objIS = objHttp.getInputStream();
			BufferedReader objReader = new BufferedReader(new InputStreamReader(objIS));

			while ((strLine = objReader.readLine()) != null) {
				if ((beginIndex = strLine.indexOf("{sid:")) != -1) {
					if ((idx = strLine.indexOf("al:")) != -1
							&& (endIndex = strLine.indexOf("',ti")) != -1
							&& idx + 4 < endIndex)
						System.out.printf("[唱片集:%s]  ",strLine.substring(idx+4,endIndex));
					if ((idx = strLine.indexOf("ti:")) != -1
							&& (endIndex = strLine.indexOf("',si")) != -1
							&& idx + 4 < endIndex)
						System.out.printf("%s", strLine.substring(idx + 4,endIndex));
					if ((idx = strLine.indexOf("si:")) != -1
							&& (endIndex = strLine.indexOf("',cp")) != -1
							&& idx + 4 < endIndex)
						System.out.printf("  [歌手:%s]",strLine.substring(idx+4,endIndex));
					System.out.printf("\n");

					if ((endIndex = strLine.indexOf(".mp3")) != -1) {
						strLine = strLine.substring(beginIndex + 6, endIndex + 4);
						getMP3URL("http://xinge.baidu.com/wgns/url/" + strLine);
					}
				}
			}
		} catch (Exception e) {
			// e.printStackTrace();
		}
	}

	private void getMP3URL(String surl) throws Exception {
		String strLine;
		URL url = new URL(surl);
		HttpURLConnection objHttp = (HttpURLConnection) url.openConnection();
		objHttp.setRequestProperty("User-Agent", "mozilla/5.0");

		InputStream objIS = objHttp.getInputStream();
		BufferedReader objReader = new BufferedReader(new InputStreamReader(objIS));

		if ((strLine = objReader.readLine()) != null) {
			strLine = "http://xinge.baidu.com" + strLine;
			System.out.println(strLine); //打印查找到的MP3的真实网址
			//播放或下载的代码...
		}
		objHttp.disconnect();
		objHttp = null;
		objReader.close();
		objReader = null;
		url = null;
	}
}

 

2.获取搜狗新歌Top100的MP3真实网址

  用上面的方法不能获取搜狗新歌100的MP3真实网址,原因可能是其服务 器有更严格的限制,防止用上面的方法去恶意搜索。前两天调试代码时连接上去,接收到的页面源文件中提示输入验证码,所以就不能用程序去解析其MP3网址 了,晕,接连两天都不行,不知道是前两天调试程序连接频繁搜的太猛了还是别的什么原因,触发了网站的防恶意搜索保护。

http://music.sogou.com/song/newtop_1.html源文件片断

<td width="25"><a οnclick="window.open('http://mp3.sogou.com/down.so?t=%C0%F1%CE%EF&s=%BD%AD%D3%B3%C8%D8&w=02210600','','width=428,height=394,scrollbars=no');uigsPB('consume=phb_down');return false;" href="javascript:void(0);" target="_blank" class="link" title="链接"></a></td>

 

  源代码如下,自己对比一下,就能琢磨出与第一种方法有什么不同了。总的步骤是一样的,仍是两步:

  • 连接到http://music.sogou.com/song/newtop_1.html从接收到的数据流中查找到歌曲链接。打开这个页面的源文件,查找到window.open(,它后面用一对单引号括起来的内容就是歌曲的链接,这个链接是用于打开试听窗口的。
  • 用程序连接到这个歌曲链接,从接收到的数据流中查找以http://开头、以.mp3结尾的字符串,这个字符串就是MP3的真实网址。

Java代码

1. /*
2.  * SogouNewTop.java - 获取'搜狗音乐新歌TOP100'的MP3真实网址
3.  */
4. package
5.     
6. import
7. import
8. import
9. import
10. import
11.     
12. /**
13.  * 创建、发送HTTP请求头
14.  */
15. class
16. private
17. private
18. private
19.      BufferedReader brIn;   
20.     
21. public
22. this
23.      }   
24.     
25. public   void
26. int  beginIndex, endIndex, iPort =  80
27. 7
28. "/"
29.          String strPath = strHost.substring(endIndex);   
30. 0
31. if ( (beginIndex = strHost.indexOf( ":" )) != - 1
32. if (endIndex - beginIndex >  1
33. 1
34. 0
35.          }   
36.     
37. try
38. new
39. new  PrintWriter(socket.getOutputStream(),  true
40.     
41. // 构建HTTP请求头
42. "GET "  + strPath +  " HTTP/1.1"
43. "Host:"
44. "Referer:"
45. "Accept:*/*"
46. "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)"
47. "Connection: Keep-Alive"
48.              pwOut.println();   
49.     
50. // 调用socket.getInputStream方法时才发送HTTP请求头
51. new  BufferedReader( new
52. catch
53. "创建套接字/输入流错误。"
54. 1
55.          }   
56.      }   
57.     
58. public
59. return
60.      }   
61.         
62. public   void
63. try
64.              brIn.close();   
65.              pwOut.close();   
66.              socket.close();   
67. catch
68. "关闭套接字错误。"
69. 1
70.          }   
71.      }   
72.  }   
73.     
74.  /**   
75.   * 解析搜狗音乐新歌TOP100页面获取MP3真实网址。   
76.   */   
77. public   class
78. private   static   final  String strReferer =  "http://music.sogou.com/song/newtop_1.html"
79. private  MySocket htmlSocket =  new
80. private  MySocket urlSocket =  new
81.     
82. /*
83.      * 查找页面的歌曲链接
84.      */
85. public  SogouNewTop()  throws
86. "连接到搜狗音乐新歌TOP100\n"
87. ""
88.          htmlSocket.create(strReferer);   
89.          BufferedReader brIn = htmlSocket.getBufferedReader();   
90. int
91.     
92. while  ((strline = brIn.readLine()) !=  null
93. // 1.查找歌曲名(可省略)
94. if  ((beginIndex = strline.indexOf( "consume=phb_song" )) != - 1
95.                  strline = strline.substring(beginIndex);   
96. if  ((beginIndex = strline.indexOf( ">" )) != - 1
97. "<" )) != - 1
98. 1
99. "[歌曲名] "
100.                  }   
101. continue
102.              }   
103.     
104. // 2.查找歌曲链接
105. if  ((beginIndex = strline.indexOf( "οnclick=\"window.open(" )) != - 1
106. "http://mp3.sogou.com/down.so" )) != - 1
107. "'," )) != - 1
108.                  strline = strline.substring(beginIndex, endIndex);   
109.                  getMP3URL(strline);   
110.              }   
111.          }   
112.          htmlSocket.close();   
113.      }   
114.     
115. /**
116.      * 分析歌曲链接找到其真实网址
117.      */
118. private   void  getMP3URL(String surl)  throws
119. ""
120.          urlSocket.create(surl);   
121.          BufferedReader brIn = urlSocket.getBufferedReader();   
122. int
123.     
124. while  ((strline = brIn.readLine()) !=  null
125. if  ((beginIndex = strline.indexOf( "http://" )) != - 1
126. ".mp3" )) != - 1
127. 4
128. //打印MP3的真实地址
129. //播放或下载的代码放这......;
130. break
131.              }   
132.          }   
133.     
134.          urlSocket.close();   
135.      }   
136.  }


/*
 * SogouNewTop.java - 获取'搜狗音乐新歌TOP100'的MP3真实网址
 */
package jmp123.player;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.Socket;

/**
 * 创建、发送HTTP请求头
 */
class MySocket {
	private String strReferer;
	private Socket socket;
	private PrintWriter pwOut;
	BufferedReader brIn;

	public MySocket(String strReferer) {
		this.strReferer = strReferer;
	}

	public void create(String surl) {
		int beginIndex, endIndex, iPort = 80;
		String strHost = surl.substring(7);
		endIndex = strHost.indexOf("/");
		String strPath = strHost.substring(endIndex);
		strHost = strHost.substring(0, endIndex);
		if( (beginIndex = strHost.indexOf(":")) != -1) {
			if(endIndex - beginIndex > 1)
				iPort = Integer.parseInt(strHost.substring(beginIndex+1, endIndex));
			strHost = strHost.substring(0, beginIndex);
		}

		try {
			socket = new Socket(strHost, iPort);
			pwOut = new PrintWriter(socket.getOutputStream(), true);

			// 构建HTTP请求头
			pwOut.println("GET " + strPath + " HTTP/1.1");
			pwOut.println("Host:" + strHost);
			pwOut.println("Referer:" + strReferer);
			pwOut.println("Accept:*/*");
			pwOut.println("User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322)");
			pwOut.println("Connection: Keep-Alive");
			pwOut.println();

			// 调用socket.getInputStream方法时才发送HTTP请求头
			brIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		} catch (IOException e) {
			System.out.println("创建套接字/输入流错误。");
			System.exit(1);
		}
	}

	public BufferedReader getBufferedReader() {
		return brIn;
	}
	
	public void close() {
		try {
			brIn.close();
			pwOut.close();
			socket.close();
		} catch (IOException e) {
			System.out.println("关闭套接字错误。");
			System.exit(1);
		}
	}
}

/**
 * 解析搜狗音乐新歌TOP100页面获取MP3真实网址。
 */
public class SogouNewTop {
	private static final String strReferer = "http://music.sogou.com/song/newtop_1.html";
	private MySocket htmlSocket = new MySocket(strReferer);
	private MySocket urlSocket = new MySocket(strReferer);

	/*
	 * 查找页面的歌曲链接
	 */
	public SogouNewTop() throws Exception {
		System.out.println("连接到搜狗音乐新歌TOP100\n");
		String strline = "";
		htmlSocket.create(strReferer);
		BufferedReader brIn = htmlSocket.getBufferedReader();
		int beginIndex, endIndex;

		while ((strline = brIn.readLine()) != null) {
			// 1.查找歌曲名(可省略)
			if ((beginIndex = strline.indexOf("consume=phb_song")) != -1 ) {
				strline = strline.substring(beginIndex);
				if ((beginIndex = strline.indexOf(">")) != -1
						&& (endIndex = strline.indexOf("<")) != -1) {
					strline = strline.substring(beginIndex+1, endIndex);
					System.out.println("[歌曲名] " + strline);
				}
				continue;
			}

			// 2.查找歌曲链接
			if ((beginIndex = strline.indexOf("οnclick=\"window.open(")) != -1
					&& (beginIndex = strline.indexOf("http://mp3.sogou.com/down.so")) != -1
					&& (endIndex = strline.indexOf("',")) != -1) {
				strline = strline.substring(beginIndex, endIndex);
				getMP3URL(strline);
			}
		}
		htmlSocket.close();
	}

	/**
	 * 分析歌曲链接找到其真实网址
	 */
	private void getMP3URL(String surl) throws Exception {
		String strline = "";
		urlSocket.create(surl);
		BufferedReader brIn = urlSocket.getBufferedReader();
		int beginIndex, endIndex;

		while ((strline = brIn.readLine()) != null) {
			if ((beginIndex = strline.indexOf("http://")) != -1
					&& (endIndex = strline.indexOf(".mp3")) != -1) {
				strline = strline.substring(beginIndex, endIndex + 4);
				System.out.println(strline);	//打印MP3的真实地址
				//播放或下载的代码放这......;
				break;
			}
		}

		urlSocket.close();
	}
}

 

MP3网站的加密方法经常变更,到目前为止这种方法可用,不能保证一直可用。应用示例到http://jmp123.sf.net/ 下载最新的程序(zip压缩包),程序用法见其中的readme.txt。