近来想抓取新浪新闻排行榜(http://news.sina.com.cn/hotnews/)的一些信息,经过半天的捣鼓后发现了一些有趣的东西。
1. 获取数据
打开网页查看源文件后发现了一些关键代码:
<script type="text/javascript" src="http://top.news.sina.com.cn/ws/GetTopDataList.php?top_type=day&top_cat=www_all&top_time=20120603&top_show_num=100&top_order=ASC&js_var=all_1_data">
//src的参数为排行系统生成的js链接(这里是每天,出国,取十条,顺序的取值,返回值是studyaboard_1_data是的取值链接)
</script>
很明显,获取数据的链接是:
2. 分析格式
在浏览器里输入这个地址,即可获得类似下面的数据(只列出开头一部分):
var all_1_data = {"conf":{"js_var":"all_1_data"},"data":[{"id":"5099","title":"\u5c24\u91d1\u8d5b\u5218\u7fd412\u79d287\u593a\u5ba4\u59163\u8fde\u51a0 \u8d85\u98ce\u901f\u5e73\u4e16\u754c\u7eaa\u5f55","media":"\u65b0\u6d6a\u4f53\u80b2","author":"all","comment_url":"http:\/\/comment5.news.sina.com.cn\/comment\/comment4.html?channel=ty&newsid=6-12-6084893&style=0","url":"http:\/\/sports.sina.com.cn\/o\/2012-06-03\/03116084893.shtml","create_date":"2012-06-03","create_time":"03:11:00","cat_name":"www_all","top_time":"20120603","top_num":"1","ext1":"False","ext2":"","ext3":"","ext4":"","ext5":""},
这些JSON格式的数据很容易看出,每一条项目有id, title, media, author, comment_url, url, create_date, create_time, cat_name, top_time, top_num等字段。要注意的时,字段的内容如果是中文的话,是以Unicode方式编码的,例如
\u5c24\u91d1\u8d5b\u5218\u7fd412\u79d287\u593a\u5ba4\u59163\u8fde\u51a0\u8d85\u98ce\u901f\u5e73\u4e16\u754c\u7eaa\u5f55
转换为中文就是:
尤金赛刘翔12秒87夺室外3连冠超风速平世界纪录
有了上面的这些信息,我们就可以方便获取新闻排行榜的数据了。
3. 展现数据
接着,我们继续来看看页面的一些代码
<script language="JavaScript">
var MyNewsList;
var i;
var j=0;
var sCnt=0;
var eCnt=0;
var fCnt=0
var MyNews = new Object();
for (i in all_1_data.data) //studyaboard_1_data.data这个参数为链接返回值那个对象的名称
{
if(j>19)
{
break;
}
MyNewsList=all_1_data.data[i];
var month = MyNewsList['create_date'].split("-")[1];
var day = MyNewsList['create_date'].split("-")[2];
var hour= MyNewsList['create_time'].split(":")[0];
var min= MyNewsList['create_time'].split(":")[1];
MyNewsList['comment_url'] = MyNewsList['comment_url'].replace("http://comment4.news.sina.com.cn/comment/comment4.html", "http://comment5.news.sina.com.cn/comment/skin/default.html");
var url=MyNewsList['url'];
var sports = new RegExp("sports.sina.com.cn");
var ent = new RegExp("ent.sina.com.cn");
var finance = new RegExp("finance.sina.com.cn");
var news = new RegExp("news.sina.com.cn");
var mil = new RegExp("mil.sina.com.cn");
var society=new RegExp("news.sina.com.cn/s/");
var bbs=new RegExp("/bbs/");
if(sports.test(url)){
if(sCnt>3){
continue;
}else{
sCnt++;
}
}
if(ent.test(url)){
if(eCnt>1){
continue;
}else{
eCnt++;
}
}
if(finance.test(url)){
if(fCnt>5){
continue;
}else{
fCnt++;
}
}
if(!sports.test(url) && !ent.test(url) && !finance.test(url) && !news.test(url) && !mil.test(url)){
continue;
}
if(society.test(url) || bbs.test(url))
{
continue;
}
j++;
document.write("<tr><td>"+j+"</td><td class='ConsTi'><a href='"+MyNewsList['url']+"' target='_blank'"+">"+MyNewsList['title']+"</a></td><td>"+MyNewsList['media']+"</td><td>"+month+"-"+day+" "+hour+":"+min+"</td><td><a href='"+MyNewsList['comment_url']+"' target='_blank'>发表评论</a></td></tr>");
//可以在这里对列表样式对应设置一般都是<li>...</li>
}
</script>
这段代码的主要作用就是将获取到的数据输出到页面。值得注意的是,它只会输出前20条记录(if(j>19) { break; })。
4. 继续分析
对于获取数据的链接,我对这些参数比较有兴趣,于是进行了一些试验。
试验办法:去掉一个参数,再获取数据,然后对比原始链接得到的数据。
试验结果:
js_var默认值是data
top_order默认值是ASC
top_show_num默认值是10
top_time必须得有,否则会出错:“排行日前参数格式不正确”
top_cat必须得有,否则会出错:"排行分类指定不能为空"
5. 一些问题
通过以上分析可知,新浪这个页面会获取100条新闻记录,但只把前面的20条展示出来,这个有浪费流量之嫌,退一步来说也会拖慢页面加载速度。
以上是本人分析新浪新闻排行榜的一些杂记和个人看法。
注:有关Unicode编码的可参看
JDK自带的native2ascii工具完全揭密:http://lavasoft.blog.51cto.com/62575/12689