说明:

  使用了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. 强大的自适应jQuery焦点图特效

    jQuery焦点图切换自适应效果 自适应jQuery焦点图特效是一款支持移动端的响应式jQuery焦点图插件,支持flexible布局,支持移动触摸事件等. 今天我们要来分享一款很灵活的jQuery焦 ...

  2. JS美女图片切换带视觉差

    使用JS实现,多张图片动态切换查看效果:http://hovertree.com/texiao/js/21/ 效果图: 转自:http://hovertree.com/h/bjaf/iamhxcyk. ...

  3. OA项目——总结

    先来张大致结构图: 项目链接:https://github.com/shuai7boy/YM_OA

  4. 背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令

    [源码下载] 背水一战 Windows 10 (23) - MVVM: 通过 Binding 或 x:Bind 结合 Command 实现,通过 ButtonBase 触发命令 作者:webabcd ...

  5. 配置Java SSL 访问网站证书

    最近在开发 Java 访问 Azure ServiceBus 时遇到SSL证书问题,导致JAVA报错,不能正常访问,报错信息如下: javax.net.ssl.SSLException: Connec ...

  6. Java中的可变长参数

    可变长参数的定义 与一般方法没多大差别,只不过形参多了...(三个点) 方法名(数据类型 ... 变量名){} 小案例: public class ParamDemo { public static ...

  7. 使用KMP算法判断是否为旋转词

    假设有两个字符串A.B,要判断它们是否为旋转词,只需构造一个"A+A"字符串,再与B比较,若B为A的旋转词,则使用KMP算法是可以得到结果的 代码如下: import java.u ...

  8. 03-树1 树的同构 (C语言链表实现)

    #include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h& ...

  9. android 音乐播放器

    本章以音乐播放器为载体,介绍android开发中,通知模式Notification应用.主要涉及知识点Notification,seekbar,service. 1.功能需求 完善音乐播放器 有播放列 ...

  10. 浅谈c#中的delegate和event了

    一.开篇忏悔 对自己最拿手的编程语言C#,我想对你说声对不起,因为我到现在为止才明白c#中的delegate和event是怎么用的,惭愧那.好了,那就趁着阳光明媚的早晨简单来谈谈delegate和ev ...