可能大家看到过有些网站有以下功能(如图所示)
这里显示的文章的来源网站,并不是URL,而且网站的名称。事实上,这个网站名称是根据这篇文章的URL推断出来的,即给你一个网页的URL,找出这个URL对应的网站名。举例说,URL为http://www.sina.com.cn/ ,那么网站名便是“新浪”。为了实现这个功能,到网上查了很多资料,没有发现好的解决方法,只好用一种比较笨的方法来解决。思路是在数据库建一张表,记录URL和网站名的映射关系,这样就可以直接根据URL查找到对应的网站名了。这种方法是最直接的,但建立这样一张表,需要手工录入足够多的网站URL和网站名,显然不是一项轻松的工作。
后来想了想,有没有这样的网站,把所有的网站URL和网站名都列出来,这样我只需要写一个简单的程序,从这个网站里提取信息,保存到数据库就行了,省下了很多功夫。在百度里搜索一下,居然真的找到这种类型的网站:http://top.chinaz.com/list.aspx,这个网站列出了中国排名前5213位的网站URL及网站名,如图所示:
只要把这些排名网站的信息提取出来,就可以向数据库插件5000多个网站的URL及网站名。jsoup这个开源项目可以很方便地提取网页内容,下面用jsoup提取网站URL及名称。
1.先到jsoup的官方网下载最新版的JAR包:http://jsoup.org/
2.jsoup的官网有很详细的教程,这里便不介绍其用法了
3.查看http://top.chinaz.com/list.aspx的源代码,找出要提取的内容的特征
4.根据特征提取网站URL及名称,代码如下:
/**
* 从http://top.chinaz.com/提取排名前5000多位的网站URL及网站名
* @return
*/
public Map<String,String> getRealmNameFromChinaz(){
//用于保存网站URL和网站名
Map<String,String> map=new HashMap<String,String>();
Document doc=null;
try {
//总共有522页
for(int i=1;i<=522;i++){
//每一页的链接是有规律的,http://top.chinaz.com/list.aspx?p=第几页
doc = Jsoup.connect("http://top.chinaz.com/list.aspx?p="+i).get();
//提取网站名和URL
Elements elements=doc.select("div.info a");
for(Element element:elements){
String name=element.text();//网站名
String url=element.nextElementSibling().text();//网站URL
map.put(url, name);//保存到map中
}
}
} catch (IOException e) {
e.printStackTrace();
}
return map;
}
这样就可以获取5000多个网站的URL和网站名了,然后再把这些结果保存到数据库,供查询使用。抓取并保存到数据库,整个过程大概需要3分钟。
以上方法可以大大减轻录入网站URL和网站名的工作,如果需要从其他网站抓取类似的信息,也可以采用这种方法。当然,互联网上的网站不计其数,想把所有的网站URL和网站名都收录是不大可能的,我们只要收录大部分的主流网站(也就是排名靠前的网站)就行了,剩下的一些网站可以采用手工录入的方式,保存到数据中。
把网站的URL和网站名保存到数据库只是第一部分工作,第二部分工作要做的是根据URL查询名称。大多时候,我们拿到的URL并不是www.oschina.net这样的链接,而且类似http://www.oschina.net/project,这时候需要我们对URL进行处理,提取原始URL中的域名(即www.oschina.net)。这也不是一件很容易的事,因为网站的域名可能有多级,如http://justjavac.iteye.com/blog/1727586,要把这个网址转为www.iteye.com,要费一定功夫。目前提取顶级域名的开源项目有libtld,也可以自己通过正则表达式等方法实现一个提取顶级域名、二级域名的类,从而完成任务。
注:菜鸟一个,博客内容写得很肤浅,只是用于记录工作学习中遇到的一些问题及解决方法,这些方法在别人看来可能不值一提,仅供参考。