借鉴了jeff heaton的程序,把下载的网页存放到mysql数据库中(不知道这样做好不好),使用sourceforce.net上的htmlparser包来解析html。
类名为htmlparserTest,实现了 com.heaton.bot包中的ISpiderReportable接口
初始化数据库连接:
public SaveToDatabase stdb=null;
public void getConnection(){ try{ String sqlurl="jdbc:mysql://localhost:3306/searchdb?user=root&password=821210"; stdb=new SaveToDatabase("com.mysql.jdbc.Driver",sqlurl); } catch(Exception e){ } }
_spider = new Spider( this,_url.getText(),new HTTPSocket(),100,wl);初始化spider,构造函数可以看bot-package包,100为线程个数,wl我使用的是基于sql管理队列。(对于jeff heaton这个包,需要仔细看看,这样才能知道spider的工作流程)
processPage方法:(ISpiderReportable接口中定义的)
public void processPage(HTTP page) { _pagesCount++; UpdateTarget ut = new UpdateTarget();
ut._t = page.getURL(); SwingUtilities.invokeLater(ut); if(isHTMLPage(page)){ processFile(page); } }
这里isHTMLPage是判断是不是html网页,我没有考虑图片还有js,doc等
public boolean isHTMLPage(HTTP file){ String url=file.getURL(); int a=url.lastIndexOf('.'); String name=url.substring(++a); if(name.equals("gif")||name.equals("jpg")||name.equals("jpeg")||name.equals("swf")||name.equals("css")||name.equals("js")||name.equals("rar")||name.equals("doc")||name.equals("ppt")){ return false; } else return true; }
processFile方法实现如下:(使用了java swing 来解析html)
public synchronized void processFile(HTTP file) { try { String url=file.getURL(); HTMLPage page=new HTMLPage(file); page.open(url,null); //如果html中不包含title标签,则把url作为标题 String titlename= page.getUrlTitle();; if(titlename.equals("> >")){ titlename=url; } java.text.SimpleDateFormat dateFormatter =new java.text.SimpleDateFormat("yyyy-MM-dd"); java.util.Date d=new java.util.Date(); String date = dateFormatter.format(d); //判断当前url是否在数据库中有记录 int count=stdb.GetURLCount(url); if(count<1){//增加 stdb.insertToDb(url,titlename,page.getParagraphAndLinkalt(),date); } else //更新 stdb.updataDb(titlename,page.getParagraphAndLinkalt(),date,url); } catch ( Exception e ) { Log.logException("Can't save output file: ",e); }
}
其中stdb是SaveToDatabase一个对象,SaveToDatabase类具体代码为:
class SaveToDatabase{ protected Connection con; protected PreparedStatement preGetStatus; protected PreparedStatement preinsert; protected PreparedStatement preupdate; protected PreparedStatement preClearDb; SaveToDatabase(String driver,String url)throws SQLException,ClassNotFoundException{ Class.forName(driver); con=DriverManager.getConnection(url); preClearDb=con.prepareStatement("DELETE FROM visited_tab;"); preGetStatus=con.prepareStatement("SELECT count(*) as qty FROM visited_tab WHERE url=?;"); preinsert=con.prepareStatement("INSERT INTO visited_tab(url,title,text,encode,last_modify_time) VALUES(?,?,?,?,?);"); preupdate=con.prepareStatement("UPDATE visited_tab SET title=?,text=?,encode=?,last_modify_time=? WHERE url=?;"); } public int GetURLCount(String url){ int count=0; try{ preGetStatus.setString(1,url); ResultSet rs=preGetStatus.executeQuery(); rs.next(); count =rs.getInt("qty"); } catch(Exception e){ } return count; } public void ClearDb(){ try{ preClearDb.executeUpdate(); } catch(Exception e){ } } public void insertToDb(String url,String title,String text,String encode,String last_modify_time){ try{ preinsert.setString(1,url); preinsert.setString(2,title); preinsert.setString(3,text); preinsert.setString(4,encode); preinsert.setString(5,last_modify_time); preinsert.executeUpdate(); } catch(Exception e){ System.err.println("error02"+e); } } public void updataDb(String title,String text,String encode,String last_modify_time,String url){ try{ preupdate.setString(1,title); preupdate.setString(2,text); preupdate.setString(3,encode); preupdate.setString(4,last_modify_time); preupdate.setString(5,url); preupdate.executeUpdate(); } catch(Exception e){ System.err.println("error03"+e); } }}数据库中只做了几项,呵呵,刚开始作,简单些。
实现的过程有很多在com.heaton.bot包中,需要自己看SpiderSQLWorkload.java、SpiderWorker.java、Spider.java、SpiderDone,java四个包。自己机子只能跑100——300个线程,多了就out of memory,呵呵,程序基本实现了爬虫功能
但是解析html过程中还是有问题,下载html一些注释,还有一些乱麻。不知道那位大虾可以指点一下
