• 基于SourceForge.net+Java+JMS技术实现的分布式爬虫系统


    第一章 引言 1
    1.1 研究背景 1
    1.1.1 SourceForge.net 1
    1.1.2 需求复用 1
    1.1.3 实验项目 1
    1.1.4 爬虫简介 2
    1.2 国内外研究现状 2
    1.2.1 java爬虫框架 2
    1.2.2 python爬虫框架 2
    1.3 本文的主要研究内容 3
    1.4 论文的主要工作和组织结构 3
    第二章 分布式爬虫综述 4
    2.1 分布式爬虫类型 4
    2.1.1 应用于搜索引擎 4
    2.2.2 基于主题的爬虫 4
    2.2.3 用户个性化爬虫 4
    2.2 MapReduce 5
    2.3 分布式爬虫系统的架构 6
    2.3.1 主从式 6
    2.3.2 自治式 7
    2.3.3 混合式 7
    2.4 爬取策略 8
    2.5 部署网络 8
    第三章 技术基础 9
    3.1 网络通信技术 9
    3.1.1 RPC 9
    3.1.2 WebService 9
    3.1.3 RMI 10
    3.1.4 JMS 11
    3.1.5 activeMQ 14
    3.2 队列 14
    3.3 线程池 14
    3.4 jsoup 16
    第四章 需求分析和概要设计 17
    4.1 功能需求分析 17
    4.1.1 需求概述 17
    4.1.2 用例图 18
    4.1.3 用例描述 18
    4.2 性能需求分析 20
    4.2.1 可扩展性 20
    4.2.2 可靠性 21
    4.2.3 负载均衡 21
    4.2.4 降低通信开销 21
    4.3 概要设计 21
    4.3.1 系统结构图 21
    4.3.2 流程图 22
    4.3.3 性能需求的设计 23
    第五章 模块详细设计与实现 25
    5.1 模块详细设计 25
    5.2.1 CenterNode模块 25
    5.2.2 TaskNode模块 27
    5.2 模块实现 30
    5.2.1 关键部分代码 30
    5.2.2 运行截图 33
    5.3 数据库设计 36
    第六章 总结与展望 37
    6.1 总结 37
    6.2 展望 37
    参考文献 38
    致谢 39
    第四章 需求分析和概要设计
    4.1 功能需求分析
    4.1.1 需求概述
    经过分析,我决定在不同的网页内分别爬取开源项目的不同数据,这些网页类别包括:目录页,详情页,用户需求页。先根据目录页得到所有项目最基本的信息:名字和url,以及项目所在的页码–得到页码主要是为了处理数据方便。将项目url作为种子url放入爬取队列,然后按照广度优先策略分三次迭代:第一次迭代在项目详情页爬取项目的基本信息,如项目简介、特征、评分等等;第二次迭代在项目详情页爬取每个项目的推荐项目;第三次迭代在用户需求页爬取用户对于该项目提出的改进需求。
    每一页要爬取的数据如下:
    目录页(如https://sourceforge.net/directory/page=1):名字,所在页码,主页。
    详情页(如https://sourceforge.net/projects/clonezilla):所属目录,简介,特征,评分,周下载量,项目主页(指的不是在sourceforge.net上的主页,而是项目自身的主页,比如有的项目在github上的地址),最后更新时间,注册时间,平台或系统,目标用户群,开发语言,三个推荐项目的名称和主页。
    用户需求页(如https://sourceforge.net/p/clonezilla/feature-requests/70):需求精要,标签,优先级,创建时间,状态(已解决或未解决),内容。
    执行过程为:主节点选择要爬取的页码作为信息发送到JMS服务器activeMQ上,任务节点从activeMQ中接收信息,根据页码在数据库查询要爬取的url,执行爬虫任务。任务执行完后,任务节点发送返回信息到activeMQ上,主节点接收到返回信息后分配新任务给该任务节点。系统执行过程如图4.1所示。
    在这里插入图片描述

    图4.1 执行过程
    4.1.2 用例图
    整个分布式爬虫系统整体上分为中心节点和任务节点两部分。中心节点的功能是监听新注册、监听返回消息和分配任务;任务节点的功能是注册、接收任务、执行任务和返回消息。
    两部分的用例图如图4.2所示:
    在这里插入图片描述

    图4.2 用例图

    package code;
    
    //生产消息
    import javax.jms.Connection;
    import javax.jms.ConnectionFactory;
    import javax.jms.DeliveryMode;
    import javax.jms.Destination;
    import javax.jms.JMSException;
    import javax.jms.MessageProducer;
    import javax.jms.Session;
    import javax.jms.TextMessage;
    
    import org.apache.activemq.ActiveMQConnection;
    import org.apache.activemq.ActiveMQConnectionFactory;
    
    import utility.Utility;
    
    public class JmsClient {
    
        private static final String USERNAME = ActiveMQConnection.DEFAULT_USER;
        private static final String PASSWORD = ActiveMQConnection.DEFAULT_PASSWORD;
        private static final String BROKEURL = Utility.activeIP;
    
        public void connect(String ip, int i) {
            //连接工厂
            ConnectionFactory connectionFactory;
            //连接
            Connection connection = null;
            //会话 接受或者发送消息的线程
            Session session;
            //消息的目的地
            Destination destination;
            //消息生产者
            MessageProducer messageProducer;
            //实例化连接工厂
            connectionFactory = new ActiveMQConnectionFactory(USERNAME, PASSWORD, BROKEURL);
    
            try {
                //通过连接工厂获取连接
                connection = connectionFactory.createConnection();
                //启动连接
                connection.start();
                //创建session
                session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
                //创建一个名称为HelloWorld的消息队列
                destination = session.createQueue(ip);
                //创建消息生产者
                messageProducer = session.createProducer(destination);
                //设置为不持久化
                messageProducer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);  
                //发送消息
                sendMessage(session, messageProducer, i);
    
                session.commit();
    
            } catch (Exception e) {
                e.printStackTrace();
            }finally{
                if(connection != null){
                    try {
                        connection.close();
                    } catch (JMSException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
        
    
        private void sendMessage(Session session, MessageProducer messageProducer, int i) throws Exception{
            //创建一条文本消息 
            TextMessage message = session.createTextMessage(i+"");
            System.out.println("发送消息:"+i);
            //通过消息生产者发出消息 
            messageProducer.send(message);
        }
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 相关阅读:
    小菜鸟的算法学习笔记——快速排序
    Golang:反射机制reflect
    PostgreSQL 难搞的事系列 --- vacuum 的由来与PG16的命令的改进 (1)
    一本通2073;三角形面积
    BDDM 2024国际会议盛邀您参加!投稿详情点击查看!
    《数据结构与算法之美》读书笔记1
    (附源码)ssm教师工作量核算统计系统 毕业设计 162307
    【编程之路】面试必刷TOP101:链表(06-10,Python实现)
    POI 中 Excel设置列的格式
    商业合作保密协议 (3)
  • 原文地址:https://blog.csdn.net/newlw/article/details/127994724