宽度优先爬虫和带偏好的爬虫

本文探讨了互联网爬虫如何遍历网页,主要介绍宽度优先遍历(BFS)策略及其在爬虫中的应用。宽度优先爬虫从种子节点开始,将超链接放入队列中依次抓取,并通过Visited表避免重复。此外,还提到了带偏好的遍历,即根据网页优先级进行遍历。文章以Java为例,展示了如何实现宽度优先的爬虫程序,利用HttpClient和HtmlParser工具包。
摘要由CSDN通过智能技术生成

        爬虫程序是如何遍历互联网,把网页全部抓取下来的呢?互联网可以看成一个超级大的”图“,每个页面可以看作是一个"节点"。页面中的连接可以看成是图的"有向边”。因此,能够通过图的遍历的方式对互联网这个超级大“图”进行访问。图的遍历通常可分为宽度优先遍历和深度优先遍历两种方式。但是深度优先遍历可能会在深度上过“深”地遍历或者陷入“黑洞”,大多数爬虫都不采用这种方式。另一方面,在爬取的时候,有时候也不能完全按照宽度优先遍历的方式,而是给待遍历的网页赋予一定的优先级, 根据这个优先级进行遍历,这种方法称为带偏好的遍历。


1、宽度优先遍历互联网

    整个的宽度优先爬虫过程就是从一系列的种子节点开始, 把这些网页中的 “ 子节点 ” ( 也就是超链接)提取出来, 放入队列中依次进行抓取。 被处理过的链接需要放入一张表( 通常称为Visited表)中。每次新处理一个链接之前,需要查看这个链接是否已经存在于Visited表中。如果存在,证明链接已经处理过,跳过,不做处理,否则进行下一步处理。实际的过程如图1.5所示。


如图1.5所示, 初始的URL地址是爬虫系统中提供的种子URL(一般在系统的配置文件中指定)。 当解析这些种子URL所表示的网页时, 会产生新的URL(比如从页面中的<ahref=“ http://www.admin.com”中提取出http://www.admin.com这个链接)。然后,进行以下工作:
(1)把解析出的链接和Visited表中的链接进行比较,若Visited表中不存在此链接, 表示其未被访问过。
(2)把链接放入TODO表中。
(3)处理完毕后,再次从TODO表中取得一条链接,直接放入Visited表中。
(4)针对这个链接所表示的网页,继续上述过程。如此循环往复。


2、Java宽度优先爬虫示例

Java实现一个简易的爬虫。其中用到了HttpClient和HtmlParser两个开源工具包


首先, 需要定义图1.6中所描述的 “URL队列 ” , 这里使用一个LinkedList来实现这个队列。

Queue类:

package com.bfsTest;

import java.util.LinkedList;
/**
 * 
 *队列,保存将要访问的URL
 *
 */
public class Queue {
	//使用链表实现队列
	private LinkedList queue = new LinkedList();
	//入队列
	public void enQueue(Object t){
		queue.addLast(t);
	}
	//出队列
	public Object deQueue()
	{
		return queue.removeFirst();
	}
	//判断队列是否为空
	public boolean isQueueEmpty()
	{
		return queue.isEmpty();
	}
	
	public boolean contains(Object t)
	{
		return queue.contains(t);
	}
	public boolean empty()
	{
		return queue.isEmpty();
	}

}

除了URL队列之外,在爬虫过程中,还需要一个数据结构来记录已经访问过的URL。
每当要访问一个URL的时候,首先在这个数据结构中进行查找,如果当前的URL已经存
在,则丢弃它。这个数据结构要有两个特点:
1、结构中保存的URL不能重复。
2、能够快速地查找 (实际系统中URL的数目非常多,因此要考虑查找性能) 。
针对以上两点,我们选择HashSet作为存储结构。


LinkQueue类:

package com.bfsTest;
import java.util.*;

public class LinkQueue {
	//已访问的url集合
	private static Set visitedUrl = new HashSet();
	//待访问的url 集合
	private static Queue unVisitedUrl = new Queue();
	//获得URL队列
	public static Queue getUnVisitedUrl()
	{
		return unVisitedUrl;
	}
	//添加到访问的URL队列中
	public static void addVisitedUrl(String url)
	{
		visitedUrl.add(url); 
	}
	//移除访问过的URL
	public static void removeVisitedUrl(String url)
	{
		 visitedUrl.remove(url);
	}
	//未访问的URL出队列
	public static Object unVisitedUrlDeQueue()
	{
		return unVisitedUrl.deQueue();
	}
	//保证每个URL只被访问一次
	public static void addUnvisitedUrl(String url)
	{
		if(url != null && !url.trim().equals("")
				&& !visitedUrl.contains(url)
				&& !unVisitedUrl.contains(url))
			unVisitedUrl.enQueue(url);
	}
	//获得已经访问的URl数目
	public static int getVisitedUrlNum()
	{
		return visitedUrl.size();
	}
	
	//判断未访问的URL队列是否为空
	public static boolean unVisitedUrlsEmpty()
	{
		return unVisitedUrl.empty();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值