- 浏览: 304646 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
popotang:
关注raphael,从中学习一下
基于jquery, raphael的WEB流程设计器 -
Getwaysun:
拜读了,写得非常好
iframe跨域session丢失问题 -
chen4w:
good!
Geoserver & Openlayers 学习笔记 -
holysky:
Caused by: org.springframework. ...
Spring对属性文件加密解密应用 -
holysky:
希望能解决一下!
Spring对属性文件加密解密应用
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代码
- /*
- * 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 ;
- }
- }
/* * 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
onclick="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代码
- /*
- * 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( "onclick=\"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();
- }
- }
/* * 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("onclick=\"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。
发表评论
-
一些有用的开源项目
2013-07-09 07:22 971cbtoolhttp://code.google.com/p/ ... -
Javadoc转换chm帮助文档的四种方法总结
2012-01-04 22:48 967关键词 Java ... -
解决IE和FF下载中文名称的文件文件名乱码的问题.
2011-11-02 14:06 1056下载前判断浏览器类型 采用不同的文件名编码方式 网 ... -
iframe跨域session丢失问题
2010-09-09 03:47 2180哎呀,在做项目的时候,碰到一个很棘手的问题。在一个应用中通过i ... -
java 正则表达式 过滤html标签
2010-09-07 08:47 1072import java.util.regex.Matcher; ... -
验证码
2010-09-03 19:47 696<%@ page contentType="i ... -
JSON与JAVA数据的转换
2010-08-26 08:52 1228JSON-lib这个Java类包用于把bean,map和XML ... -
JAVA中使用FTPClient上传下载资源
2010-03-25 11:36 16866最近发现apache很多jar包非常好用,刚好项目中要实现ft ... -
HttpClient 学习整理
2009-12-19 12:40 839HttpClient 学习整理 ... -
用RMI建立一个分布式Java应用程序详解
2009-10-29 13:46 767RMI,远程方法调用(Remote Method Invoca ... -
Java RMI之HelloWorld篇
2009-10-29 13:39 967Java RMI 指的是远程方法调用 (Remote Me ... -
java中使用log4j将日志信息写入数据库中
2009-08-06 13:09 2385首先将log4j的jar包和Logging的jar包导入到 ... -
log4j详解
2009-07-29 21:19 927在实际编程时,要使Log4 ... -
学习Flex和BlazeDS的十三个理由
2009-06-18 10:43 765本文列述了13个Java程序 ... -
Java 语言的类、属性、方法各有哪些修饰符?简述各修饰符的使用条件
2009-06-13 10:32 28821、 类的修饰符分为: ... -
windows 平台的cvs服务器配置
2009-06-10 14:42 9641: 大家做开发的时候就是都会用到cvs版本控制,那么怎样制作 ... -
Java正则表达式匹配、替换HTML内容
2009-06-09 23:09 2881曾经了解过JavaScript的正则表达式,知道其功 ... -
Java代理模式
2009-04-08 19:21 28651.代理模式 代理模式的作用是:为其他对象提供一种代理以控 ... -
final 关键字的理解
2009-04-08 19:20 811final使得被修饰的变量"不变",但是由 ... -
Java1.6.0实现系统托盘技术
2009-04-06 21:06 1382实现系统托盘图标,借用dll动态链接库,用JAVA ...
相关推荐
喜马拉雅MP3地址获取软件是一款喜马拉雅MP3下载工具,可以帮助用户获取到喜马拉雅MP3地址,操作简单方便,只需输入音乐链接地址即可。 喜马拉雅MP3地址获取软件使用说明: 1.下载并运行软件,输入存储路径以及下载...
网络小蜜蜂是一个网页视频,图片等资料的下载工具,它可以下载...首先根据用户指定的网址,访问该网页并分析,然后抓取指定格式的MP4视频或图片或MP3的真实URL, 最后下载到你指定的文件夹。这样你可以把该网址的所有
在线电视电影地址/Flash/MP3/Email地址/FTP 等网络地址嗅探工具,并可以自定义嗅探文件。...各种网络电视电影软件也逃不过,现在你可以轻松获取电影真实地址了。支持启动NetTransport及FlashGet下载。
在线电视电影地址/Flash/MP3/Email地址/FTP 等网络地址嗅探工具,并可以自定义嗅探文件。...各种网络电视电影软件也逃不过,现在你可以轻松获取电影真实地址了。支持启动NetTransport及FlashGet下载。
依存关系检查requirements.txt以获取python依赖项要转换为mp3,请运行以下命令: brew install libsndfile lamebrew install --with-libsndfile fluidsynth神经网络结构以下程序使用经过Midi数据训练的前馈神经网络...
2> 网络--获取数据(图片、网页、xml、Json等) 3> 如何把数据通过HTTP协议提交到网络上的Web应用(get / post ) 数据大于2k的时候 A.通过Get方式提交参数给Web应用 B.通过Post方式提交参数给Web应用 C.使用...
可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和...
能以超低的CPU使用率达到最快的的格式转换速度,Freemake Video Converter还能自动监测最佳转换参数并切换CUDA和DXVA的开关来获取更好的转换质量,快速将源文件输出为AVI、WMV、MP4、MKV、FLV、3GP、MP3等目标格式。...
本书以Android应用程序的开发为主题,并结合真实的案例向读者详细介绍了Android的基本组件的使用及应用程序开发的整个流程。本书的讲述由浅入深,实例全面并典型,几乎囊括了所有和Android应用相关的项目。全书分为...
可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和...
可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和...
可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和...
可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和...
Java源码下载 1个目标文件 摘要:Java源码,网络相关,HTTP Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的...
Java源码下载 1个目标文件 摘要:Java源码,网络相关,HTTP Java实现HTTP连接与浏览,Java源码下载,输入html文件地址或网址,显示页面和HTML源文件,一步步的实现过程请下载本实例的Java源码,代码中包括丰富的...
可直接输入文件名或网络地址,但必需事先连入网络。 Java编写的山寨QQ,多人聊天+用户在线 21个目标文件 摘要:JAVA源码,媒体网络,山寨QQ,Java聊天程序 Java编写的山寨QQ,多人聊天+用户在线,程序分服务端和...
<br>2007/7/04 Version 3.1.9 beta <br>Updates: 1) 增强页面信息采集功能的链接分析能力,当采集图片或超链接的时候会自动将相对路径转化为真实的网络路径,并且修正了采集功能的一些已知BUG。...