`
wb17534806
  • 浏览: 11631 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

一个简单的蜘蛛程序

阅读更多

一个简单的蜘蛛程序,没有实现多线程,只考虑了一些特定的情况。

一句话:一切从简!

下载提供测试页面。

源码:

package com.wans.spider;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.sun.java_cup.internal.internal_error;
import com.sun.org.apache.bcel.internal.generic.NEW;

public class MySpider1 implements Runnable {


 static ArrayList<String> waitUrlList = new ArrayList<String>();            //等待处理的urls
 static ArrayList<String> disposeUrlList = new ArrayList<String>();     //要处理的urls
 static ArrayList<String> errorUrlList = new ArrayList<String>();           //处理出错的urls
 static ArrayList<String> overUrlList = new ArrayList<String>();            //处理完成的urls
 //static ArrayList<String> outUrlList = new ArrayList<String>();             //发现外链urls
 
 static ArrayList<String> Allhost=new ArrayList<String>();                  //存放主机
 
 static String webUrl = "http://192.168.0.25:8080/test_net_for_spider/";
 //static String webUrl = "http://127.0.0.1:8080/test_net_for_spider/";       //对某个网站进行爬取
 static long outtime = 1000;                                                //连接超时时间
 static int ceng = 5;                                                       //查询的层数
 static int timeout = 10000;                                                //连接超时
 static int sheng = 4;                                                      //爬取深度
 static int threads = 1;                                                    //抓取线程数为1
 
 
 public static void main(String[] args) {
  MySpider1 spider1 = new MySpider1();
  for (int i = 1; i <= threads; i++) {
   Thread thread = new Thread(spider1);
   thread.start();
  }
 }

 //使用多线程提高效率
 public void run() {
  //调用主体方法
  body();
 }
 
 //主体方法
 private static void body() {
  //输出爬取开始基本信息
  info();  
  //将爬取网站加入等待处理的urls
  waitUrlList.add(webUrl);
  System.out.println("webUrl:"+webUrl+" 已添加到 "+waitUrlList);
  //检查等待处理的urls是否为空,不为空,将urls传到disposeUrlList。为空,停止爬取。
  //处理urls,发现链接,判断是否是外链。是,加入outUrlList。不是,加入等待队列。
  for(int i=1;i<=sheng;i++) {
   if(waitUrlList.isEmpty() || waitUrlList.size() == 0) {
    System.out.println("\r爬取结束。。。。");
    overinfo();//统计爬取结束信息
    break;
   } else {
    disposeUrlList.addAll(waitUrlList);//将等待urls加入处理urls
    System.out.println("waitUrlList 加入 disposeUrlList 中 进行处理");
    waitUrlList.clear(); //清空urls,为下次使用做准备。
    for (String url : disposeUrlList) {
     //获取url中的超链接,保证无重复。
     ArrayList<String> urlsList = getUrls(url);
     for (String urlt : urlsList) {
      if(!disposeUrlList.contains(urlt) && !overUrlList.contains(urlt)) {
       waitUrlList.add(urlt);
      }
     }
    }
    overUrlList.addAll(disposeUrlList);  //完成urls
    System.out.println("处理连接结束,写入 overUrlList");
    System.out.println("处理过连接的个数:   "+overUrlList.size());    
    disposeUrlList.clear();   
   }
  }
 }
 
 
 //获取网页里的超链接,加入等待urls
 private static ArrayList<String> getUrls(String url) {
  ArrayList<String> urlsArrayList = new ArrayList<String>();   //存放链接
  //获得网页内容
  String urlConent = getHtml(url);
  if(urlConent != null) {
   //分析文本内容,获取链接
   String regex="<a href.*</a>"; 
   String output=null;                                 //第一次提取的<a href  *  </a>
   String outputUrl=null;                            //对第一次提取的Url再次过滤
   Pattern pa=Pattern.compile(regex, Pattern.DOTALL);
   Matcher ma=pa.matcher(urlConent);                            //初次过滤  
   while(ma.find()){
    output=ma.group().trim();
    regex="<a\\s+href\\s*=\\s*\"?(.*?)[\"|>]";             //再次过滤
    // regex="http\\s*\"?(.*?)[\"|>]";
    Pattern paa=Pattern.compile(regex,Pattern.DOTALL);
    Matcher maa=paa.matcher(output);
    while(maa.find()){
     outputUrl=maa.group().trim();
     // System.out.println();
     // System.out.println(outputUrl);
     if (outputUrl.length() < 1) {
      continue;
     }
     //********************************************
     //根据实际情况 过渡网页的某些垃圾信息
     outputUrl=outputUrl.replace("<a href=", "");
     outputUrl=outputUrl.replace("\"", "");
     outputUrl=outputUrl.replace(">", "");
     outputUrl=outputUrl.replace("/>", "");
     outputUrl=outputUrl.replace("class=","");
     outputUrl=outputUrl.replace("target=_blank", "");
     outputUrl=outputUrl.replace("'target=_blank'", "");
     outputUrl=outputUrl.replace("'_blank'", "");
     outputUrl=outputUrl.replace("target=_self", "");
     outputUrl=outputUrl.replace("target=", "");
     outputUrl=outputUrl.replace("style=", "");
     outputUrl=outputUrl.replace("../", "");
     outputUrl=outputUrl.replace("#", "");
     outputUrl=outputUrl.replace("title=", "");
     outputUrl=outputUrl.replace("<a  href=", "");
     outputUrl=outputUrl.replace("'", "");
     //*********************
//     int endUrl=outputUrl.indexOf(" ");            //处理url有空格问题
//     if(endUrl>0){                              //要是有空格才截断
//      outputUrl=outputUrl.substring(0,endUrl);  //以空格为结束
//     }
     //*************************
     outputUrl=outputUrl.trim();    //过滤空间
     if(outputUrl.length()>0){
      if(outputUrl.indexOf("://")==-1){    //处理相对地址
       int length=webUrl.length();
       int find=webUrl.lastIndexOf("/")+1;
       if(length==find){
        outputUrl=webUrl+outputUrl;           //  如果以/结尾
       }else{
        outputUrl=webUrl+"/"+outputUrl;     //  如果不以 /结尾
       }
      }
      int begin2=outputUrl.lastIndexOf("//")+2;  //检查是否是以 //结尾
      if(begin2==outputUrl.length()){
       outputUrl=outputUrl.substring(0, outputUrl.length()-1); //  把   //变成/
      }
      if(!urlsArrayList.contains(outputUrl)){               //去掉重复的url
       urlsArrayList.add(outputUrl);
      }
     }
    }
   }
  }
  return urlsArrayList;
 }
 
 //获取网页内容
 private static String getHtml(String url) {
  StringBuffer urlConent = new StringBuffer(); //装url中内容  
  try {
   URL urlpath = new URL(url);    //对应连接地址
   String urlHost = urlpath.getHost(); //获取地址主机
   if("".equals(urlHost) && !Allhost.contains(urlHost)) {     //将主机加入
    Allhost.add(urlHost);
   }
   HttpURLConnection urlcon = (HttpURLConnection)urlpath.openConnection();
   HttpURLConnection.setFollowRedirects(true); //设置此类是否应该自动执行 HTTP 重定向(响应代码为 3xx 的请求)。
   urlcon.setInstanceFollowRedirects(false);     //返回此 HttpURLConnection 的 instanceFollowRedirects 字段的值。
   urlcon.setConnectTimeout(timeout);            //设置超时,这里直接调用系统设置的
   //将读超时设置为指定的超时,以毫秒为单位。用一个非零值指定在建立到资源的连接后从 Input 流读入时的超时时间。
   //如果在数据可读取之前超时期满,则会引发一个 java.net.SocketTimeoutException。超时时间为零表示无穷大超时。
   //此方法的一些非标准实现会忽略指定的超时。要查看读入超时设置,请调用 getReadTimeout()。
   urlcon.setReadTimeout(timeout); 
   urlcon.connect();  //打开到此 URL 引用的资源的通信链接(如果尚未建立这样的连接)。
   System.out.println("\r正在连接 ...");
   System.out.println("地址是: "+url);
   String contentType=urlcon.getContentType();
   System.out.println("方式为: "+contentType+"    状态: "+urlcon.getResponseMessage());
   System.out.println("正在读取HTML流 ......");
   
   String s="";
   BufferedReader br = new BufferedReader(new InputStreamReader(urlcon.getInputStream()));
   while((s=br.readLine()) != null) {
    urlConent.append(s);
   }
   double size = urlConent.length();
   System.out.println("ok   读取了 "+size/1024+"KB");
  } catch (MalformedURLException e) {   
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }  
  return urlConent.toString();  
 }
 
 //爬取结束信息
 private static void overinfo() {
  String info = null;
  info += "本次爬取网页总数为:"+overUrlList.size()+"\r";
  info += "错误网页总数为:"+errorUrlList.size()+"\r";
  info += "爬取结束时间:" + getTime();
  System.out.println(info);
 }
 
 //输出爬取开始基本信息
 private static void info() {
  String info = null;
  info += "爬取开始时间:" + getTime() + "\r";
  info += "主机地址:" + webUrl + "\r";
  info += "超时时间是:" + outtime  + "\r";
  info += "查询的层数:" + ceng + "\r";
  info += "限定主机搜索!" + "\r\r";
  info += "启动爬取程序。。。。。\r";
  System.out.println(info);
 }
 
 //获取时间
 private static String getTime() {
  SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
  return format.format(new Date());
 } 
 
}
 

分享到:
评论

相关推荐

    java写的一个简单的蜘蛛程序

    【描述】:“用java写的一个简单的蜘蛛程序,用java写的一个简单的蜘蛛程序用java写的一个简单的蜘蛛程序” 描述虽然重复,但强调了这个程序的核心特性——它是用Java编写的,并且是“简单”的。简单通常意味着该...

    简单的蜘蛛程序

    本主题将围绕如何构建一个简单的蜘蛛程序展开讨论。 【描述】:“简单的蜘蛛程序” 创建一个简单的蜘蛛程序通常涉及到以下几个核心步骤: 1. **URL管理**:首先,你需要定义一个起始URL,这是爬虫开始工作的起点...

    百度强引蜘蛛程序易语言.zip

    标题中的“百度强引蜘蛛程序易语言”表明这是一个使用易语言编写的应用程序,目标是吸引搜索引擎,特别是百度的网络爬虫(蜘蛛)来提高网站的抓取频率和收录率。在SEO(搜索引擎优化)领域,这被称为“引蜘蛛”或...

    快车蜘蛛池站群程序 v2.0

    1 程序带有简易后台 2 文章内容可以自动采集 或者自动组合生成 3 程序伪静态 动态可一键开关 4 内置近50个模版 可随机调用,也可以选择缓存固定。 5 今日昨日蜘蛛数量全权掌握。 6 提供自助开发模版标签。 7 每个...

    用c#写的一个简单的蜘蛛程序

    在C#中实现一个简单的蜘蛛程序涉及到的技术要点包括: ##### 1. HTTP请求处理 - **WebRequest**类提供了基础的HTTP请求功能,可以用来发送GET、POST等类型的请求。 - 示例代码: ```csharp HttpWebRequest ...

    一个蜘蛛程序(C#)

    【标题】:“一个蜘蛛程序(C#)” 在IT领域,蜘蛛程序(也称为网络爬虫或Web爬虫)是用于自动浏览互联网并抓取网页内容的软件。在本项目中,我们将关注一个用C#语言编写的蜘蛛程序。C#是一种强类型、面向对象的语言...

    java写的简单蜘蛛程序

    Java编写的简单蜘蛛程序,通常是指使用Java语言实现的网络爬虫软件,它能够自动抓取互联网上的网页信息。在编程领域,网络爬虫是一种自动化技术,用于从万维网中提取大量数据,用于数据分析、搜索引擎索引或其他特定...

    蜘蛛程序,google抓取,简单

    标题中的“蜘蛛程序,google抓取,简单”指的是网络爬虫技术,它是搜索引擎的重要组成部分,尤其是Google这样的全球知名搜索引擎。网络爬虫,也被称为网页蜘蛛或机器人,是一种自动浏览互联网并抓取网页信息的程序。...

    一个简单的java网络蜘蛛程序,非常适合初学者

    Java网络蜘蛛程序,也称为网络爬虫或网页抓取器,是用于自动化地从...通过学习和实践这个简单的Java网络蜘蛛程序,初学者可以建立起对网络爬虫基本概念和技术的理解,为进一步深入学习和开发更复杂的爬虫项目打下基础。

    一个简易的用C语言编写的蜘蛛纸牌小游戏

    【标题】中的“一个简易的用C语言编写的蜘蛛纸牌小游戏”表明我们要讨论的是一个使用C语言开发的蜘蛛纸牌游戏。蜘蛛纸牌是一种流行的单人纸牌游戏,通常在计算机上玩,这里它是通过编程语言C实现的。 【描述】的...

    程序设计综合实践蜘蛛纸牌JAVA代码

    程序设计综合实验所需的代码,简单的蜘蛛纸牌代码,通过Java编写,易懂易上手

    网络蜘蛛程序学习1

    7. **源码分析**:可能提供一个简单的爬虫源码示例,帮助初学者理解爬虫的实现过程。 8. **实际应用案例**:通过实际案例展示网络爬虫在数据分析、市场调研等方面的应用。 在这个学习过程中,你将能够从零开始构建...

    简单精炼的JAVA蜘蛛程序Eclipse完整项目

    "简单精炼的JAVA蜘蛛程序Eclipse完整项目"是一个基于JAVA语言编写的爬虫程序,它被设计得简洁而高效。这里的"蜘蛛"或"爬虫"通常指的是网络爬虫,这是一种自动抓取互联网信息的程序,通过模拟浏览器行为,遍历网页并...

    蜘蛛程序for c#

    在C#中实现一个蜘蛛程序,主要涉及到以下几个关键知识点: 1. **HTTP请求与响应**:网络爬虫首先需要向目标网站发送HTTP请求,获取服务器返回的HTML响应。这通常使用`System.Net.Http.HttpClient`类来完成。你需要...

    搜索引擎蜘蛛算法与蜘蛛程序构架.doc搜索引擎蜘蛛算法与蜘蛛程序构架.doc

    深度优先策略则从起始页开始,沿着链接一路深入,直至处理完一条路径后再转至下一个起始页,这种策略在设计上相对简单。在实际应用中,搜索引擎可能会结合这两种策略,并设定访问层数限制,避免过度抓取某些网站的...

    易语言蜘蛛程序

    在【压缩包子文件的文件名称列表】中,我们看到"易语言蜘蛛程序源码",这可能是一个包含完整源代码的文件夹或单一文件,其中可能包括了主程序、配置文件、帮助文档等相关组件。用户在获得这个源码后,可以通过易语言...

Global site tag (gtag.js) - Google Analytics