说明:

  使用了htmlparser库。

  运行过程:

    从某个网址开始,摘取网页中的链接,并通过广度搜索,对这些链接递归执行上述操作。

    在以上过程中把网址存入数据库中。以防止搜索中出现环路。

    但是,程序经常进入某个网站后,会一直扫描其中的二级域名。

    于是数据库中会出现这种情况:

      jack.art.com

      han.art.com

      bob.art.com

      alice.art.com

      rose.art.com

      ...

      ...

代码:

//Robot.java  1 package robot;
 import java.net.*;
 import java.sql.SQLException;
 import java.util.Random;

 import javax.swing.JOptionPane;

 import org.htmlparser.*;
 import org.htmlparser.filters.TagNameFilter;
 import org.htmlparser.tags.LinkTag;
 import org.htmlparser.util.NodeList;
 import org.htmlparser.util.ParserException;

 import mydb.DB;
 public class Robot {
     int ff=0;

     int num=0;
     //DB db;
     Robot() throws MalformedURLException, SQLException{
         DB.getConnect("localhost","3306","robot","root","142365");
         DB.getSta();
         String url0="http://www.youku.com";//"http://localhost";
      /*  DB.rs= DB.s.executeQuery("select count(*) from urls");
         if(DB.rs.next())
         {int n=DB.rs.getInt(1);
         System.out.println(n );
         Random random = new Random();

         int ran = random.nextInt();
         ran%=n;
         ran=ran>0?ran:-ran;
         System.out.println(ran );
         DB.rs= DB.s.executeQuery("select * from urls");
         int x=0;
         while(DB.rs.next()&&x<ran){

                   System.out.println(DB.rs.getString(1)+"000" ); url0=DB.rs.getString(1);

               x++;
         }

         }*/
         //catchHref("http://localhost",num);
         catchHref(url0,num);
     }
     boolean isEndLegal(String str){
         if(str.endsWith("php")||str.endsWith("net/")||str.endsWith("com/")||str.endsWith("cn/")||str.endsWith("gov/")||str.endsWith("edu/")||str.endsWith("org/")||str.endsWith("net")||str.endsWith("com")||str.endsWith("cn")||str.endsWith("gov")||str.endsWith("edu")||str.endsWith("org")){
             return true;
         }
         return false;
     }
     boolean catchHref(String hreft ,int num) throws MalformedURLException {
         Parser     parser =null;
         NodeList nodelist=null;
         String href = "http://www.baidu.com";
         //db=new DB();
         if(ff!=0)
         if (!(hreft.startsWith("http")&&isEndLegal(hreft)&&!isInDatabase(hreft))) {
             return false;
         }
         ff=1;
         add(hreft);

             System.out.println(num);
             try {
                 parser = new Parser(hreft);
                 if(parser==null)return false;
             } catch (ParserException e) {
                 return false;
                 //e.printStackTrace();
             }
             try {
                 nodelist = parser.parse(null);
             } catch (ParserException e1) {
                 e1.printStackTrace();
             }
             if(nodelist==null)return false;
             NodeFilter filter = new TagNameFilter("A");
             if(filter==null)return false;
             nodelist = nodelist.extractAllNodesThatMatch(filter, true);
             if(nodelist==null)return false;
             for (int i = 0; i < nodelist.size(); i++) {
                 LinkTag link = (LinkTag) nodelist.elementAt(i);
                 href = link.getAttribute("href");
                 if(href==null)return false;
                 System.out.println(href );
                 catchHref(href,num);

             }
             num++;
         return true;
     }
 void add(String str){

         try {
             DB.s.execute("insert into urls2(url)values('"+str+"');");
             DB.commit();
             System.out.println("add");
         } catch (SQLException e) {
             //e.printStackTrace();return ;
             //JOptionPane.showMessageDialog(null, "数据库添加失败");
             //System.exit(-1);

         }

         return ;
     }
     boolean isInDatabase(String str){

         try {
             DB.rs= DB.s.executeQuery("select * from urls where url like'"+str+"%';");
             if(DB.rs.next()){System.out.println(DB.rs);return true;}
         } catch (SQLException e) {
             e.printStackTrace();
             JOptionPane.showMessageDialog(null, "数据库查找失败");
             System.exit(-1);
         }
         return false;
     }
     public static void main(String[] args)
             throws MalformedURLException, ParserException, SQLException {
         Robot robot = new Robot();
     }
 }
//DB.java  1 package mydb;
 import java.sql.*;
 import java.util.ArrayList;

 import javax.swing.*;
 //import com.mysql.jdbc.Driver;
 public class DB {

     public static Connection conn = null;
     public static ResultSet rs = null;
     public static Statement s = null;
     public DB() {
         conn = null;
         s = null;
         rs=null;

     }
     /*
     String getResult(ResultSet rs) {
         String str = "Book\t\tOwnerID\tOwnerName\n";
         // System.out.println("\nno\tname\tsex\tsalary");
         try {
             while (rs.next()) {
                 StringBuilder builder = new StringBuilder(rs.getString(1));
                 builder.append("\t\t");
                 builder.append(rs.getString(2));
                 builder.append("\t");
                 builder.append(rs.getString(3));
                 builder.append("\n");
                 str += builder.toString();
             }
         } catch (Throwable e) {

         }
         // System.out.println();
         return str;
     }*/

     public static Connection getConnect(String IP,String port,String database,String user,String password){
         try {
             // Class.forName("org.gjt.mm.mysql.Driver").newInstance();
             Class.forName("com.mysql.jdbc.Driver");
         } catch (ClassNotFoundException e1) {
             e1.printStackTrace();
             JOptionPane.showMessageDialog(null, "数据库包未找到");
             System.exit(-1);
         } // .newInstance();

         try {
             conn = DriverManager.getConnection(
                     "jdbc:mysql://"+IP+":"+port+"/"+database+"?useUnicode=true&characterEncoding=utf8", user,
                     password);//autoReconnect=true&useUnicode=true&characterEncoding=utf8
         } catch (SQLException e1) {
             e1.printStackTrace();
             JOptionPane.showMessageDialog(null, "数据库无法连接");
             System.exit(-1);
         }

         try {
             conn.setAutoCommit(false);
         } catch (SQLException e1) {

             e1.printStackTrace();
         }

         return conn;
     }
     public static Statement getSta(){
         try {
             s = conn.createStatement();
         } catch (SQLException e1) {

             e1.printStackTrace();
             JOptionPane.showMessageDialog(null, "无法建立数据库语句");
             System.exit(-1);
         }
         return s;
     }

     public    static int commit(){
         try {
             conn.commit();
         } catch (SQLException e) {

             e.printStackTrace();
             JOptionPane.showMessageDialog(null, "对数据库更改无法应用");

         }
         return 0;
     }
     public static void closeConnect() {
         try {
             rs.close();
         } catch (SQLException e) {
             e.printStackTrace();
             JOptionPane.showMessageDialog(null, "数据库结果集无法关闭");

         }
         try {
             s.close();
         } catch (SQLException e) {

             e.printStackTrace();
             JOptionPane.showMessageDialog(null, "数据库语句无法关闭");

         }

         try {
             conn.close();
         } catch (SQLException e) {

             e.printStackTrace();
             JOptionPane.showMessageDialog(null, "与数据库的连接无法关闭");
         }
 /*
         try { // perform a clean shutdown
             DriverManager.getConnection("jdbc:derby:;shutdown=true");

         } catch (SQLException se) {

             if (((se.getErrorCode() == 50000)
                     && ("XJ015".equals(se.getSQLState())))) {
                 // we got the expected exception
                 System.out.println("Derby shut down normally");
                 // Note that for single database shutdown, the expected
                 // SQL state is "08006", and the error code is 45000.
             } else {
                 System.err.println("Derby did not shut down normally");
                 // JOptionPane.showMessageDialog(null, "数据库关闭错误");
                 se.printStackTrace();
             }
         }*/
     }

 }

程序写于大三上学期。

2016.4.12更新博客。

END

爬虫(Java实现)的更多相关文章

  1. 老李分享:网页爬虫java实现

    老李分享:网页爬虫java实现   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性能测试,测试工具开发等工作为目标.如果对课程感兴趣,请大家咨询qq:908821 ...

  2. CVE漏洞爬虫java代码依赖-TestNG

    TestNG是Java中的一个测试框架,而该CVE漏洞爬虫示例中所涉及到的java代码中, \Crawler\src\com\***\ThreaderRun.java文件在导入import org.t ...

  3. 初入爬虫(java)

    public class CrawlerUtil { public static void main(String [] args) throws IOException { // 创建默认的http ...

  4. 多线程爬虫Java调用wget下载文件,独立线程读取输出缓冲区

    写了个抓取appstore的,要抓取大量的app,本来是用httpclient,但是效果不理想,于是直接调用wget下载,但是由于标准输出.错误输出的原因会导致卡住,另外wget也会莫名的卡住. 所以 ...

  5. 网络爬虫Java实现抓取网页内容

    package 抓取网页; import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream; ...

  6. SuperSpider(简书爬虫JAVA版)

    * 建站数据SuperSpider(简书)* 本项目目的:* 为练习web开发提供相关的数据:* 主要数据包括:* 简书热门专题模块信息.对应模块下的热门文章.* 文章的详细信息.作者信息.* 评论区 ...

  7. 201521123081《java程序设计》 第13周学习总结

    本次作业参考文件 正则表达式参考资料 1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 参考资料:XMind 2. 书面作业 Q1. 网络基础 1.1 比较 ...

  8. 201521123006 《java程序设计》 第13周学习总结

    1. 本周学习总结 1.以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.j ...

  9. 201521123010 《Java程序设计》第13周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...

  10. 201521123037 《Java程序设计》第13周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图.OneNote或其他)归纳总结多网络相关内容. 2. 书面作业 1. 网络基础 1.1 比较ping www.baidu.com与ping cec.jmu ...

随机推荐

  1. T- SQL性能优化详解

    摘自:http://www.cnblogs.com/Shaina/archive/2012/04/22/2464576.html 故事开篇:你和你的团队经过不懈努力,终于使网站成功上线,刚开始时,注册 ...

  2. php怎么获取input输入框中的值去数据库比较显示出来

    前端: <!--商品查询--> <input type="text" name="bianhao" value="" ma ...

  3. java反编译获取源码

    最近在研究反射,想做一个东西,把运行的java程序饭编译(Decompile)成.java文件.现思路如下: 1.写出程序反编译一个类 2.将所有类反编译 3.java代码注入一个正在运行的java程 ...

  4. ABP之模块分析

    本篇作为我ABP介绍的第三篇文章,这次想讲下模块的,ABP文档已经有模块这方面的介绍,但是它只讲到如何使用模块,我想详细讲解下它模块的设计思路. ABP 框架提供了创建和组装模块的基础,一个模块能够依 ...

  5. 10、ASP.NET MVC入门到精通——Model(模型)和验证

    本系列目录:ASP.NET MVC4入门到精通系列目录汇总 模型就是处理业务,想要保存.创建.更新.删除的对象. 注解(通过特性实现) DisplayName Required StringLengt ...

  6. Html + Css思维导图

    最近整理的一份Html和Css的思维导图,共享给初学者使用. 各个知识点的详细案例介绍,后期会分阶段依次发布,希望对大家学习html和css有帮助. 如果对文中的知识点有异议,欢迎随时拍砖! 后期也回 ...

  7. CSS3过渡详解-遁地龙卷风

    第二版 0.环境准备 (1)过渡需要浏览器的支持,使用这些属性要加上浏览器厂商的前缀,我用的chrome49已经不需要前缀了, -o- Opera -webkit- Safari.Chrome -mo ...

  8. 弹出页面遮罩层,以及web端和移动端阻止遮罩层的滑动。

    最近项目遇到了遮罩层的一些问题,总结一下: 弹出遮罩层 遮罩层弹出有非常多的方法,这里只写出本人用的代码,使用jq操作dom的方法进行实现的. <style>.box{position:a ...

  9. SDWebImage原理及使用(转)

    转自http://www.cnblogs.com/jys509/p/5199997.html SDWebImage托管在github上.https://github.com/rs/SDWebImage ...

  10. android 7.0 学习笔记(一)

    导读 增强的Doze模式 后台优化 Data Saver 一.增强的Doze模式 Android N对Android M引进的Doze模式进行了进一步的增强,变化体现在两个方面.一方面是降低了进入Do ...