一个最简单的网络爬虫的实现

网络爬虫 听起来有点复杂,但最基本的原理却不难,就是给你一个网址,然后你把该网站的内容下载下来,筛选出上面其他的url地址,保存在一个队列里,然后访问其中一个url,再下载,再筛选,直到满足某个条件。

当然,其中还牵扯到各种策略,什么广度优先,深度优先,但我们这里是最简单的网络爬虫,所以不讨论。


好,那么我们从最简单的原理入手。首先,我们要建立一个保存网址的数据结构。

public class queue {  
  
    private LinkedList queue;  
      
    //构造函数  
    public queue()  
    {  
        queue=new LinkedList();  
    }  
    //入队列  
    public void enQueue(Object elem)  
    {  
        queue.addLast(elem);  
    }  
    //出队列  
    public Object deQueue()  
    {  
        return queue.removeFirst();  
    }  
    //判断队列是否为空  
    public boolean isEmpty()  
    {  
        return queue.isEmpty();  
    }  
    //判断队列中是否含有某个元素  
    public boolean contains(Object elem)  
    {  
        return queue.contains(elem);  
    }  
}  
再然后,我们再写一个类来保存我们的网址。

public class MyQueue {

	// 已访问的URL的队列
	private Set visitedQueue;
	// 未访问的URL的队列
	private queue unVisitedQueue;

	// 构造函数
	public MyQueue() {
		visitedQueue = new HashSet<String>();
		unVisitedQueue = new queue();
	}

	// 加入已访问的队列
	public void addURL(String url) {
		visitedQueue.add(url);
	}

	// 返回已访问的队列
	public Set getVisited() {
		return this.visitedQueue;
	}

	// 移除访问过的URL
	public void removeUrl(String url) {
		visitedQueue.remove(url);
	}

	// 未访问过的URL出队列
	public String getUnVURL() {
		return (String) unVisitedQueue.deQueue();
	}
    public boolean contains(String url){
    	if(!unVisitedQueue.contains(url))
    		return true;
    	return false;
    }
	// 加入未访问过的URL
	public void addUnVURL(String url) {
		if ((url != null)
				&& (!url.trim().equals("") && (!visitedQueue.contains(url)) && (!unVisitedQueue
						.contains(url) ))&&url.contains("http") ) {
			unVisitedQueue.enQueue(url);
		}
	}

	// 获得已访问的URL的数目
	public int getVisitedNum() {
		return visitedQueue.size();
	}

	// 判断未访问的队列是否为空
	public boolean isEmpty() {
		return unVisitedQueue.isEmpty();
	}
}

最后,我们写主程序。当你输入一个网址,我们用Httpclient(需要你自己下载JAR包)来下载它的内容,并用正则表达式来筛选其中的url地址,并在控制台上输入爬去到的网址,当网址大于2000的时候,程序终止。

public class HttpDownLoader {
	static int count = 0;

	public static void main(String[] args) {
		HttpClient httpClient = new HttpClient();

		// 设置 Http 连接超时 5s
		httpClient.getHttpConnectionManager().getParams()
				.setConnectionTimeout(5000);

		Scanner sc = new Scanner(System.in);
		MyQueue mq = new MyQueue();
		mq.addUnVURL(sc.next());
		while (count < 1000 && !mq.isEmpty()) {
			String sh = mq.getUnVURL();
			GetMethod getMethod = new GetMethod(sh);
			// 设置 get 请求超时 5s
			getMethod.getParams().setParameter(HttpMethodParams.SO_TIMEOUT,
					5000);
			// 设置请求重试处理
			getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
					new DefaultHttpMethodRetryHandler());
			mq.addURL(sh);
			try {
				StringBuilder sb = new StringBuilder();
				int status = httpClient.executeMethod(getMethod);
				BufferedReader br = null;
				if (status == HttpStatus.SC_OK) {
					br = new BufferedReader(new InputStreamReader(
							getMethod.getResponseBodyAsStream()));
					String line = null;
					while ((line = br.readLine()) != null) {
						sb.append(line);
					}
				} else if ((status == HttpStatus.SC_MOVED_PERMANENTLY)
						|| (status == HttpStatus.SC_MOVED_TEMPORARILY)
						|| (status == HttpStatus.SC_SEE_OTHER)
						|| (status == HttpStatus.SC_TEMPORARY_REDIRECT)) {
					Header head = getMethod.getResponseHeader("location");
					if (head != null) {
						String newURL = head.getValue();
						if ((newURL == null) || newURL.equals("")) {
							newURL = "/";
							GetMethod getMethod1 = new GetMethod(newURL);
							httpClient.equals(getMethod1);
							br = new BufferedReader(new InputStreamReader(
									getMethod1.getResponseBodyAsStream()));
							String line = null;
							while ((line = br.readLine()) != null) {
								sb.append(line);
							}
						}
					}
				}

				// String shtml = getMethod.getResponseBodyAsString();
				String mode = "(?<=(href=\")).*?(?=\")";
				// String mode ="<[aA]\\s*(href=[^>]+)>(.*?)</[aA]>" ;
System.out.println(sb.toString());
				Pattern p = Pattern.compile(mode);
				Matcher m = p.matcher(sb.toString());
				while (m.find()) {
					String url = m.group();
					if (url.contains("http") && mq.contains(url)) {
						System.out.println(url);
						mq.addUnVURL(url);
						count++;
					}
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				// e.printStackTrace();
			}
			getMethod.releaseConnection();
		}
		// getMethod.releaseConnection();
		System.out.println("访问了" + mq.getVisitedNum() + "个网页");

	}
}
然后我们的简易网络爬虫就完成了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,简单介绍下网络爬虫   网络爬虫是通过网页的链接地址来寻找网页,从网站某一个页面(设置为主页)开始,读取网页的内容,找到网页中的其它链接地址,然后通过这些链接地址寻找下一个网页,这样一直循环下去,直到这个网站所有的网页都抓取完为止。实际上,由于抓取技术的限制以及存储技术、处理技术的限制,要完全抓取网站的所有网页是不可能的,也是不实际的!本着从用户需要为出发点,实际需要抓取的网页往往是有限的,只需抓取符合用户要求的网页即可! 抓取网页的策略 在抓取网页的时候,网络爬虫一般有两种策略(即两种搜索方法),广度优先和深度优先。 广度优先:是指网络爬虫会先抓取起始网页中链接的所有网页,然后再选择其中的一个链接网页,继续抓取在此页面中链接的所有页面。这是最常用的方式,广度优先的搜索策略可以并行处理,提高抓取速度。 深度优先:是指网络爬虫会从起始页开始,一个链接一个链接跟踪下去,处理完这条线路之后再转入下一个起始页,继续跟踪链接。这种策略较易实现,但是抓取速度慢。 由于一般不可能抓取网站的所有链接,一般会设置访问层数,即搜索深度。起始页的深度为0,起始页中的链接url深度为1,依此类推。 构造C#语言的爬虫程序 C#已经封装了HTTP访问和多线程,这对编写网络爬虫提供了方便,而要C#网络爬虫程序需要解决以下问题: HTML分析:需要某种HTML解析器来分析爬虫程序遇到的每一个页面。 页面处理:需要处理每一个下载得到的页面。下载得到的内容需要保存起来,以便进一步分析处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值