说明:

  使用了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. html&css中的文字对齐问题

    html&css的使用过程中,我们经常会遇到很多文字对齐问题.下面我要介绍一个有丁点难的文字对齐问题. 实现效果如下图所示.   两行长度不定的文字,要让它们总体水平居中,然后,这两行字要左对 ...

  2. 【JAVA并发编程实战】12、使用condition实现多线程下的有界缓存先进先出队列

    package cn.study.concurrency.ch14; import java.util.concurrent.locks.Condition; import java.util.con ...

  3. java正则表达式入门

    http://www.cnblogs.com/jingmoxukong/p/6026474.html 这篇文章写的不错

  4. LZW压缩算法——简明原理与实现

    LZW和哈夫曼编码一样,是无损压缩中的一种.该算法通过建立字典,实现字符重用与编码,适用于source中重复率很高的文本压缩.本文首先讲下LZW的编解码原理,然后给出LZW的实现code. ***** ...

  5. window搭建webpack,react,babel傻瓜教程

    首先现在的webpack教程已经很多了,写这篇的原因是因为自己在从小白开始的搭建过程中,并没有找到比较好的教程,花费了很多的时间,so 有了这篇博客,方便小白同学学习. node环境在这里不在赘述,p ...

  6. js 获取鼠标选中值

    if (window.getSelection) {//一般浏览器 userSelection = window.getSelection();} else if (document.selectio ...

  7. Sharepoint学习笔记—习题系列--70-573习题解析 -(Q144-Q146)

    Question 144You are developing a Feature that will be used in multiple languages.You need to ensure ...

  8. Material Design 概念,环境和基本属性

    Material Design 概念,环境和基本属性 Material Design是随Android 5.0推出的一种设计概念, 涉及到了跨平台和设备的视觉,动态,交互设计等方面.   设计概念 M ...

  9. 基于Ruby的watir-webdriver自动化测试方案与实施(二)

    接着基于Ruby的watir-webdriver自动化测试方案与实施(一) http://www.cnblogs.com/Javame/p/4159360.html 继续 ... ...   回顾 软 ...

  10. Windows平台下利用APM来做负载均衡方案 - 负载均衡(下)

    概述 我们在上一篇Windows平台分布式架构实践 - 负载均衡中讨论了Windows平台下通过NLB(Network Load Balancer) 来实现网站的负载均衡,并且通过压力测试演示了它的效 ...