在(1)的基础上,我有了一些想法。我没有参考过网络搜索引擎的原理,纯粹的猜想:
现在这个程序只能抓取指定的url中的html,而google那样的似乎是抓网络中所有的网站。这个怎么想都没思路。
如果只抓取指定url的html,就只能实现搜索指定网站的内容的功能了。即使是搜索指定的网站也需要爬遍所有的该网站所有的网页。我的想法是取出首页中每个href中的url,然后继续爬这url里面的页面,然后继续继续进行下去(终止条件当然是该该网站所属的url)。所以我利用正则表达式找到了存在于body标签之内的所有的url,还没有进行重复性检查。我认为这个要等到连数据库时再进行,因为解决问题始终是要关联到数据库中的。
另外我把抓取的html存到了一个txt文件中。
在刚开始的程序中,首先存在的一个问题是 抓取的html顺序存在问题,原来原作者在spider()函数中多加了一个线程,所以导致两个线程同时抓取,顺序当然就紊乱了
import java.io.*;
import java.net.*;
import java.util.regex.*;
public class Spider{
private HttpURLConnection huc;
private InputStream is;
private BufferedReader reader;
private String url;
private BufferedWriter writer;
private int num=0;
private Boolean isBodyStart=false;
private Pattern bodyStart=Pattern.compile("<body");//匹配<body,即body标签开始
private Pattern href=Pattern.compile("(href=)((/")|(/'))([a-zA-z]+://[^//s]*)((/")|(/'))");//匹配herf="url"或href='url'
private Pattern hrefUrl=Pattern.compile("[a-zA-z]+(://[^((/")|(/'))]*)");//匹配href中的url
public Spider(String url){
try {
huc=(HttpURLConnection)new URL(url).openConnection();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
try {
huc.setRequestMethod("GET");
} catch (ProtocolException e) {
e.printStackTrace();
}
try {
huc.setUseCaches(true);
huc.connect();
} catch (IOException e) {
e.printStackTrace();
}
try {
is=huc.getInputStream();
reader=new BufferedReader(new InputStreamReader(is,huc.getContentType().equals("text-html; charset=gb2312")?"gb2312":"UTF-8"));
// writer = new BufferedWriter(new FileWriter("res.txt",true));//append
writer = new BufferedWriter(new FileWriter("res.txt"));
String str;
while((str=reader.readLine())!=null){
if(bodyStart.matcher(str).find())isBodyStart=true;
writer.write(str);
writer.newLine();
writer.flush();
String temp;
if(isBodyStart){//只取<body>中的url
if(href.matcher(str).find()){//是否找到href字段
Matcher matcher=hrefUrl.matcher(str);//开始寻找url
if(matcher.find()){
MatchResult result=matcher.toMatchResult();
temp=str.substring(result.start(), result.end());
System.out.println(temp);
num++;//测试用,查看找到多少个url,以便继续往里爬,未检测重复问题,我认为现在还不是时候
}
}
}
}System.out.print(num);
} catch (IOException e) {
e.printStackTrace();
}finally{
try {
writer.close();
reader.close();
is.close();
huc.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String [] args){
Spider sp=new Spider("http://www.csdn.net");
sp.run();
}
}
后续的工作的想法:
程序结构估计要重写了,因为要向找到的url中爬行
更远的,搜索的关键字找到的各个网页的排序,自然涉及到 一个优先级,优先级的计算也要涉及到 经验系数等,比如,关键字在网页中出现的次数,是否在标题中出现,是否在<h1>出现,用户搜索的次数等等,扯远了。。。
另外找到了一个索引搜索的利器 Lucene,先研究研究!