热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

用JAVA实现简单爬虫多线程抓取

在循环爬取得基础上进行多线程爬虫,本程序中使用的三个线程,线程为实现runnable接口,并使用对象锁防止并发共同去访问同一个对象。让三个线程同时爬去同一个url并且得到的新的url不重复。

在循环爬取得基础上进行多线程爬虫,本程序中使用的三个线程,线程为实现runnable接口,并使用对象锁防止并发共同去访问同一个对象。让三个线程同时爬去同一个url并且得到的新的url不重复。


import java.io.*;
import java.net.*;

public class WebCrawler{

    public static void main(String[] args){
        runcrawler t1=new runcrawler();
        runcrawler t2=new runcrawler();
        runcrawler t3=new runcrawler();
        t1.start();
        t2.start();
        t3.start();     
    }
}

class runcrawler extends Thread{

    String s1=";
    String url="http://www.sina.com";
    static int i=0;
    static String [] urlcOnntion=new String[100];   

    public void run() {

        newCrawler cr=new newCrawler(url,s1,urlconntion);
        String s2=cr.find();
        while(urlconntion[90]==null){
            //线程锁,防止并发导致的线程安全
            synchronized(this)
            {
            if(s2==null){
                cr=new newCrawler(url,s1,urlconntion);
                s2=cr.find();
                 }
            System.out.println(s2);
            cr=new newCrawler(s2, s1,urlconntion);
            urlconntion[i++]=s2;        
            s2=cr.find();       
            }
        }       
    }   
}

 class newCrawler {

    String url=null;
    String prefix=null;
    //爬去过的url地址集合
    String[] urlcOnntion=null;

    //爬虫类的构造函数
    newCrawler(String url,String prefix,String[] urlconntion){

        this.url=url;
        this.prefix=prefix;
        this.urlcOnntion=urlconntion;

    }

    //根据类的url开始爬取新的url实现循环爬取
    public String find(){
        URL u=null;
        URLConnection con=null;
        BufferedReader bfr=null;
        String rpurl=null;
        try {
            u=new URL(url);
            con=u.openConnection();
            //模拟成用户,访问部分网站,部分网站会拒绝爬虫爬取
            con.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
            InputStream is=con.getInputStream();
            bfr=new BufferedReader(new InputStreamReader(is));
            String s;
            while((s=bfr.readLine())!=null){
                if(s.indexOf(prefix)>=0)
                     {

                        rpurl=getUrl(s);
                        if(urlrepetition(rpurl)!=-1){
                            return rpurl;
                        }

                     }

            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                bfr.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;

    }

    //判断url是否被爬去过,如果被爬去可返回-1,如果没有则返回1
    public int urlrepetition(String rpurl){

        int i=0;
        while(urlconntion[i]!=null){
            if(urlconntion[i++].equals(rpurl)){
                return -1;
            }
        }
        return 1;
    }

    //从爬去过的源码中截取url地址;
    public String getUrl(String s){

        int index1=s.indexOf(prefix);
        s=s.substring(index1+9);
        int index2=s.indexOf("\"");
        s=s.substring(0,index2);
        return s;
    }

}

运行结果:
这里写图片描述


  • 总结:
    1.自己刚刚接触爬虫,感觉这程序虽然实现了,但是在效率上不是特别高,自己嵌套了三个循环以上,这样在时间和空间上耗费比较多。
    2.上一个写的循环爬去的问题还是没解决。

推荐阅读
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 本文详细介绍了GetModuleFileName函数的用法,该函数可以用于获取当前模块所在的路径,方便进行文件操作和读取配置信息。文章通过示例代码和详细的解释,帮助读者理解和使用该函数。同时,还提供了相关的API函数声明和说明。 ... [详细]
  • GetWindowLong函数
    今天在看一个代码里头写了GetWindowLong(hwnd,0),我当时就有点费解,靠,上网搜索函数原型说明,死活找不到第 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • 代理模式的详细介绍及应用场景
    代理模式是一种在软件开发中常用的设计模式,通过在客户端和目标对象之间增加一层中间层,让代理对象代替目标对象进行访问,从而简化系统的复杂性。代理模式可以根据不同的使用目的分为远程代理、虚拟代理、Copy-on-Write代理、保护代理、防火墙代理、智能引用代理和Cache代理等几种。本文将详细介绍代理模式的原理和应用场景。 ... [详细]
  • HashMap的相关问题及其底层数据结构和操作流程
    本文介绍了关于HashMap的相关问题,包括其底层数据结构、JDK1.7和JDK1.8的差异、红黑树的使用、扩容和树化的条件、退化为链表的情况、索引的计算方法、hashcode和hash()方法的作用、数组容量的选择、Put方法的流程以及并发问题下的操作。文章还提到了扩容死链和数据错乱的问题,并探讨了key的设计要求。对于对Java面试中的HashMap问题感兴趣的读者,本文将为您提供一些有用的技术和经验。 ... [详细]
  • python3 nmap函数简介及使用方法
    本文介绍了python3 nmap函数的简介及使用方法,python-nmap是一个使用nmap进行端口扫描的python库,它可以生成nmap扫描报告,并帮助系统管理员进行自动化扫描任务和生成报告。同时,它也支持nmap脚本输出。文章详细介绍了python-nmap的几个py文件的功能和用途,包括__init__.py、nmap.py和test.py。__init__.py主要导入基本信息,nmap.py用于调用nmap的功能进行扫描,test.py用于测试是否可以利用nmap的扫描功能。 ... [详细]
  • 基于移动平台的会展导游系统APP设计与实现的技术介绍与需求分析
    本文介绍了基于移动平台的会展导游系统APP的设计与实现过程。首先,对会展经济和移动互联网的概念进行了简要介绍,并阐述了将会展引入移动互联网的意义。接着,对基础技术进行了介绍,包括百度云开发环境、安卓系统和近场通讯技术。然后,进行了用户需求分析和系统需求分析,并提出了系统界面运行流畅和第三方授权等需求。最后,对系统的概要设计进行了详细阐述,包括系统前端设计和交互与原型设计。本文对基于移动平台的会展导游系统APP的设计与实现提供了技术支持和需求分析。 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • ejava,刘聪dejava
    本文目录一览:1、什么是Java?2、java ... [详细]
author-avatar
席昀2010_445_882
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有