`
cjnetwork
  • 浏览: 177310 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

web爬虫的广度优先算法

阅读更多
web爬虫中需要设计一个广度优先的算法,以控制爬虫爬行网址的先后顺序,这里用一个链表实现,用链表是因为链表的插入速度够快。

设计思路:
1、取下一个地址:从链表的头部取出一个,并将头部元素删除
2、加入地址池:将URL地址加入到适当的位置

   为了保证加入的时候能够加入到合适的地址,最容易想到的办法就是遍历那个地址池,但遍历的效率确实不高,当地址池中数量增大的时候,消耗在遍历上的cpu资源过多,导致爬行效率降低。还有一种方法就是记录每一个深度的URL地址的最后一个元素在地址池中索引,当加入的时候就不需要遍历地址池,只需通过需要加入的URL地址,找到同级URL地址在地址池中的索引,然后加入到地址池中,加入位置为这个索引的后面一个,并且更新索引表,当然如果没有找到同级别的索引,这依次找上一级的索引,若在回溯的过程中,都没有找到,这可以确定索引为0,即将该URL地址加入到地址池的最前面。

下面是一个索引表内容变化的例子:

深度索引
25
36

当加入一个这样的URL地址(new URL(1,"http://www.sina.com.cn"))之后
深度索引
11
26
37

当加入一个这样的URL地址(new URL(2,"http://www.baidu.cn"))之后
深度索引
11
27
38

当加入一个这样的URL地址(new URL(4,"http://tieba.baidu.cn"))之后
深度索引
11
27
38
49




实现的核心代码(代码不完整,无下载及url地址提取等)
  • Crawler.java
  • import java.util.HashMap;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    
    
    public class Crawler {
    
    	private List<Url> uncrawedUrl = new LinkedList<Url>();// 待爬行网址集合
    
    	private Map<String, Url> urls = new HashMap<String, Url>(10000);// 去重网址集合,防止重复爬
    
    	private Map<Integer, Integer> urlsIndexPointor = new HashMap<Integer, Integer>();//索引表
    
    	
    	/**
    	 * 
    	 * 将URL地址添加到未采集池
    	 * 
    	 * 
    	 * @param url
    	 * @return
    	 */
    	private boolean addUrlToPool(Url url) {
    		boolean result = false;
    		try {
    			if (!urls.containsKey(url.getUrl())) {
    				int index = 0;//默认为0,当下面的搜索过程没有找到index的时候
    				for (int i = 0; url.getDepth() - i > 0; i++) {// 从索引表中寻找需要插入的位置
    					if (urlsIndexPointor.containsKey(url.getDepth() - i)) {
    						index = urlsIndexPointor.get(url.getDepth() - i) + 1;
    						break;
    					}
    				}
    
    				uncrawedUrl.add(index, url);
    				urlsIndexPointor.put(url.getDepth(), index);
    				urls.put(url.getUrl(), url);
    				
    				//更新索引表(这个表的内容不会扩展很大,因此遍历效率可以忽略)
    				Iterator<Entry<Integer, Integer>> iter = urlsIndexPointor.entrySet().iterator();
    				while (iter.hasNext()) {
    					Entry<Integer, Integer> entry = iter.next();
    					if (entry.getKey() > url.getDepth()) {
    						entry.setValue(entry.getKey() + 1);
    					}
    				}
    				
    				result = true;
    			}
    		} catch (Exception e) {			
    			e.printStackTrace();
    		}
    		return result;
    	}
    	
    	
    	/**
    	 * 
    	 * 从URL池中取出一条未爬去过的地址
    	 * 
    	 * 
    	 * @return 没有则返回null
    	 */
    	private Url getUrlFromPool() {
    		Url result = null;
    		if (uncrawedUrl.size() > 0) {
    			result = uncrawedUrl.get(0);
    			uncrawedUrl.remove(0);
    			
    			// 更新索引表,将所有的位置指针向前移动一位
    			Iterator<Entry<Integer, Integer>> iter = urlsIndexPointor.entrySet().iterator();
    			while (iter.hasNext()) {
    				Entry<Integer, Integer> entry = iter.next();
    				if (entry.getValue() == 0) {
    					iter.remove();
    				}
    				entry.setValue(entry.getValue() - 1);
    			}			
    
    		}		
    		return result;
    	}
    }
    
    

  • Url.java
  • class Url {
    	private int depth;
    	private String url;
    
    	public int getDepth() {
    		return depth;
    	}
    
    	public String getUrl() {
    		return url;
    	}
    
    	public void setDepth(int depth) {
    		this.depth = depth;
    	}
    
    	public void setUrl(String url) {
    		this.url = url;
    	}
    }
    





    分享到:
    评论
    8 楼 cjnetwork 2010-12-13  
    haolei92 写道
    楼主是否是专门做web爬虫设计的


    不是,偶尔看看别的技术。。。 
    人不学要落后啊。。。
    7 楼 haolei92 2010-12-13  
    楼主是否是专门做web爬虫设计的
    6 楼 cjnetwork 2010-12-13  
    by5739 写道
    哎..没弄过web爬虫..不太明白为什么这样弄...我的意思是..如果用10个List分别装1-10级的url...是不是也可以?


    爬行深度是不固定的,不是简单的10或简单的是100,有的时候从一个爬行种子开始不到深度10就结束了,那开10个list就不合适,如果有的时候从一个爬行种子开始不止10个深度,那么开10个list就不够。。。
    5 楼 by5739 2010-12-13  
    哎..没弄过web爬虫..不太明白为什么这样弄...我的意思是..如果用10个List分别装1-10级的url...是不是也可以?
    4 楼 cjnetwork 2010-12-12  
    chaoren3166 写道


    注:urls可以声明成一个Set
    不知道深度优先有没有什么好的算法???



    urls之所以定义为一个map,是因为例子中的Url类目前只有两个属性,如果扩展Url类的属性,在爬取过程中需要对实例化的Url对象有一定的操作,可以方便快速的通过map定位到Url对象

    至于深度优先,个人觉得在爬虫系统中不是一个好的策略。要实现,似乎不需要要控制加入uncrawedUrl中的顺序,只要将找的url地址直接加入到列表uncrawedUrl的最后,就是实现的深度优先了。
    3 楼 chaoren3166 2010-12-12  
    cjnetwork 写道
    web爬虫中需要设计一个广度优先的算法,以控制爬虫爬行网址的先后顺序,这里用一个链表实现,用链表是因为链表的插入速度够快。

    设计思路:
    1、取下一个地址:从链表的头部取出一个,并将头部元素删除。
    2、加入地址池:将URL地址加入到适当的位置。

       为了保证加入的时候能够加入到合适的地址,最容易想到的办法就是遍历那个地址池,但遍历的效率确实不高,当地址池中数量增大的时候,消耗在遍历上的cpu资源过多,导致爬行效率降低。还有一种方法就是记录每一个深度的URL地址的最后一个元素在地址池中索引,当加入的时候就不需要遍历地址池,只需通过需要加入的URL地址,找到同级URL地址在地址池中的索引,然后加入到地址池中,加入位置为这个索引的后面一个,并且更新索引表,当然如果没有找到同级别的索引,再依次找上一级的索引,若在回溯的过程中,都没有找到,这可以确定索引为0,即将该URL地址加入到地址池的最前面。

    下面是一个索引表内容变化的例子:

    深度索引
    25
    36

    当加入一个这样的URL地址(new URL(1,"http://www.sina.com.cn"))之后
    深度索引
    11
    26
    37

    当加入一个这样的URL地址(new URL(2,"http://www.baidu.com"))之后
    深度索引
    11
    27
    38

    当加入一个这样的URL地址(new URL(4,"http://tieba.baidu.cn"))之后
    深度索引
    11
    27
    38
    49




    实现的核心代码(代码不完整,无下载及url地址提取等)
  • Crawler.java
  • import java.util.HashMap;
    import java.util.Iterator;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    import java.util.Map.Entry;
    
    
    public class Crawler {
    
    	private List<Url> uncrawedUrl = new LinkedList<Url>();// 待爬行网址集合
    
    	private Map<String, Url> urls = new HashMap<String, Url>(10000);// 去重网址集合,防止重复爬
    
    	private Map<Integer, Integer> urlsIndexPointor = new HashMap<Integer, Integer>();//索引表
    
    	
    	/**
    	 * 
    	 * 将URL地址添加到未采集池
    	 * 
    	 * 
    	 * @param url
    	 * @return
    	 */
    	private boolean addUrlToPool(Url url) {
    		boolean result = false;
    		try {
    			if (!urls.containsKey(url.getUrl())) {
    				int index = 0;//默认为0,当下面的搜索过程没有找到index的时候
    				for (int i = 0; i < url.getDepth(); i++) {// 从索引表中寻找需要插入的位置
    					if (urlsIndexPointor.containsKey(url.getDepth() - i)) {
    						index = urlsIndexPointor.get(url.getDepth() - i) + 1;
    						break;
    					}
    				}
    
    				uncrawedUrl.add(index, url);
    				urlsIndexPointor.put(url.getDepth(), index);
    				urls.put(url.getUrl(), url);
    				
    				//更新索引表(这个表的内容不会扩展很大,因此遍历效率可以忽略)
    				Iterator<Entry<Integer, Integer>> iter = urlsIndexPointor.entrySet().iterator();
    				while (iter.hasNext()) {
    					Entry<Integer, Integer> entry = iter.next();
    					if (entry.getKey() > url.getDepth()) {
    						entry.setValue(entry.getKey() + 1);
    					}
    				}
    				
    				result = true;
    			}
    		} catch (Exception e) {			
    			e.printStackTrace();
    		}
    		return result;
    	}
    	
    	
    	/**
    	 * 
    	 * 从URL池中取出一条未爬去过的地址
    	 * 
    	 * 
    	 * @return 没有则返回null
    	 */
    	private Url getUrlFromPool() {
    		Url result = null;
    		if (uncrawedUrl.size() > 0) {
    			result = uncrawedUrl.get(0);
    			uncrawedUrl.remove(0);
    			
    			// 更新索引表,将所有的位置指针向前移动一位
    			Iterator<Entry<Integer, Integer>> iter = urlsIndexPointor.entrySet().iterator();
    			while (iter.hasNext()) {
    				Entry<Integer, Integer> entry = iter.next();
    				if (entry.getValue() == 0) {
    					iter.remove();
    				}
    				entry.setValue(entry.getValue() - 1);
    			}			
    
    		}		
    		return result;
    	}
    }
    
    

  • Url.java
  • class Url {
    	private int depth;
    	private String url;
    
    	public int getDepth() {
    		return depth;
    	}
    
    	public String getUrl() {
    		return url;
    	}
    
    	public void setDepth(int depth) {
    		this.depth = depth;
    	}
    
    	public void setUrl(String url) {
    		this.url = url;
    	}
    }
    


    注:urls可以声明成一个Set
    不知道深度优先有没有什么好的算法???



    2 楼 cjnetwork 2010-12-12  
    javabkb 写道
    请教楼主,用将list转map的方式判断重复效率上好不好?

       这个方法并没有将list转换为map,两个容器的用处各不相同,list用于从未爬取的url地址中取出爬行深度最浅的一个,而map(urls这个map)的作用是用于验证url地址是否已被加入采集计划或是否已完成的采集计划。若要说有效率问题,就是有map的方法containsKey方法有一定的效率问题。
    1 楼 javabkb 2010-12-12  
    请教楼主,用将list转map的方式判断重复效率上好不好?

    相关推荐

      网络爬虫的设计与实现

      基于Webcrawler(web爬虫)设计的BFS(广度优先)策略,文章使用MD5算法,来进行0(1)时间复杂度的链接判重。为了避免频繁的查询DNS服务器,建立DNS缓存。另外,也因一般行为模式的考量,在中加入了IP范围控制技术,网页...

      Python网络爬虫与推荐算法新闻推荐平台.zip

      网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐 爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集...

      一些爬虫逆向算法.zip

      爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的...

      从零开始构建的一个宠物识别系统python代码(包括爬虫、深度学习模型和WEB服务).zip

      从零开始构建的一个宠物识别系统python代码(包括爬虫、深度学习模型和WEB服务).zip从零开始构建的一个宠物识别系统python代码(包括爬虫、深度学习模型和WEB服务).zip从零开始构建的一个宠物识别系统python代码...

      python爬虫、python实现常见算法.zip

      爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的...

      读书笔记《自己动手写网络爬虫》,自己敲的代码。主要记录了网络爬虫的基本实现,网页去重的算法,网页指纹算法,文本信息挖掘.zip

      爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的...

      C++网络爬虫项目

      WEBCRAWLER 网络爬虫实训项目 1 WEBCRAWLER 网 络 爬 虫 实 训 项 目 文档版本: 1.0.0.1 编写单位: 达内IT培训集团 C++教学研发部 编写人员: 闵卫 定稿日期: 2015年11月20日 星期五WEBCRAWLER 网络爬虫实训项目 ...

      基于网络爬虫及用户的协同过滤推荐算法的电影推荐系统.zip

      爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的...

      Safe3 Web蜘蛛爬行漏洞扫描系统 v9.6

      广度优先的爬虫技术的不会产生爬虫陷入的问题,可自定义爬行深度和爬行线程,网站目录还原技术则去除了无关结果,提高抓取效率。并且去掉了参数重复的注入页面,使得效率和可观性有了很大提高。 SQL注入状态扫描...

      Python资源大全,包括:Web框架、网络爬虫、模板引擎、数据库、数据可视化、图片处理

      资源包括环境管理、包管理、构建工具、文本处理、自然语言处理、图像处理、OCR、音频、视频、数据库、web框架、权限、电子商务、爬虫、html处理、并发和并行、服务器、网络、密码学、图像用户界面、游戏开发、日志、...

      learn_algorithms_of_the_intelligent_web:WEB智能算法,随书原始码,备注中文

      lucene实现搜索爬虫的简单实现深度优先算法爬取-&gt;索引-&gt;搜索网页 推荐系统 聚类:事物的分类 分类:把事物放到它该在的地方 分类器组合 智能技术大汇集:一个智能新闻门户 涉及到的数学知识 统计和矩阵 距离的指标 ...

      Safe3 Web漏洞扫描系统企业版v10.1特别版

      广度优先的爬虫技术的不会产生爬虫陷入的问题,可自定义爬行深度和爬行线程,网站目录还原技术则去除了无关结果,提高抓取效率。并且去掉了参数 重复的注入页面,使得效率和可观性有了很大提高。 SQL注入状态扫描...

      pdd (拼多多) 爬虫 js 解密 anti_content 参数解密及全站抓取代码思路实现.zip

      爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的...

      Safe3 Web漏洞扫描系统 v9.0

      广度优先的爬虫技术的不会产生爬虫陷入的问题,可自定义爬行深度和爬行线程,网站目录还原技术则去除了无关结果,提高抓取效率。并且去掉了参数重复的注入页面,使得效率和可观性有了很大提高。SQL注入状态扫描技术...

      Safe3 Web漏洞扫描系统 v10.1.zip

      广度优先的爬虫技术的不会产生爬虫陷入的问 题,可自定义爬行深度和爬行线程,网站目录还原技术则去除了无关结果,提高抓取效率。并且去掉了参数 重复的注入页面,使得效率和可观性有了很大提高。 SQL注入状态...

      Jobs-Recommendation-System使用Scrapy爬虫框架对招聘网站进行爬取.zip

      爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的...

      python 爬虫 web 机器学习 代码长期更新.zip

      进入21世纪,深度学习成为机器学习领域的重要突破,采用多层神经网络模型,通过大量数据和强大的计算能力来训练模型,在计算机视觉、自然语言处理和语音识别等领域取得了显著的成果。 机器学习算法在各个领域都有...

      百度地图毕业设计源码-Distributed-Web-Crawler-:有关各大语言的爬虫开发实例,需要的可以自取

      百度地图毕业设计源码 发行说明 以上内容是Yauntyour在各种语言的学习中自己动手编写,编译调试,不断修改Bug得到的...采取的策略主要有深度优先爬行策略,广度优先爬行策略。 2、增量式网络爬虫:即爬取内容发生改变

      利用kNN算法实现图书推荐系统.zip

      遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施...

    Global site tag (gtag.js) - Google Analytics