玩玩小爬虫——入门

   前段时间做一个产品,盈利方式也就是卖数据给用户,用wpf包装一下,当然数据提供方是由公司定向爬虫采集的,虽然在实际工作

中没有接触这一块,不过私下可以玩一玩,研究研究。

    既然要抓取网页的内容,肯定我们会有一个startUrl,通过这个startUrl就可以用广度优先的方式遍历整个站点,就如我们学习数据结

构中图的遍历一样。

既然有“请求网页”和“解析网页”两部分,在代码实现上,我们得需要有两个集合,分别是Todo和Visited集合,为了简单起见,我们

从单机版爬虫说起,说起爬虫,就必然逃避不了海量数据,既然是海量数据,那么性能问题不容忽视,在Todo和Visited集合的甄别

上,我们选择用Queue和HashSet,毕竟HashSet在定位查找方面只需常量的时间,下面我们用活动图来阐述一下。

在广度优先的时候,我们需要注意两个问题:

①:有的时候网页是相对地址,我们需要转化为绝对地址。

②:剔除外链。

看看其中我们一个部门的官网,广度遍历一下,看看有多少链接,当然是剔除外链的。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;

namespace ConsoleApplication1
{
    public class Program
    {
        static void Main(string[] args)
        {
            var crawler = new Crawler("http://www.weishangye.com/");

            crawler.DownLoad();

            //show 一下我们爬到的链接
            foreach (var item in Crawler.visited)
            {
                Console.WriteLine(item);
            }
        }
    }

    public class Crawler
    {
        //基地址
        public static Uri baseUri;
        public static string baseHost = string.Empty;

        /// <summary>
        /// 工作队列
        /// </summary>
        public static Queue<string> todo = new Queue<string>();

        //已访问的队列
        public static HashSet<string> visited = new HashSet<string>();

        public Crawler(string url)
        {
            baseUri = new Uri(url);

            //基域
            baseHost = baseUri.Host.Substring(baseUri.Host.IndexOf('.'));

            //抓取首地址入队
            todo.Enqueue(url);
        }

        public void DownLoad()
        {
            while (todo.Count > 0)
            {
                var currentUrl = todo.Dequeue();

                //当前url标记为已访问过
                visited.Add(currentUrl);

                var request = WebRequest.Create(currentUrl) as HttpWebRequest;

                var response = request.GetResponse() as HttpWebResponse;

                var sr = new StreamReader(response.GetResponseStream());

                //提取url,将未访问的放入todo表中
                RefineUrl(sr.ReadToEnd());
            }
        }

        /// <summary>
        /// 提取Url
        /// </summary>
        /// <param name="html"></param>
        public void RefineUrl(string html)
        {
            Regex reg = new Regex(@"(?is)<a[^>]*?href=(['""]?)(?<url>[^'""\s>]+)\1[^>]*>(?<text>(?:(?!</?a\b).)*)</a>");

            MatchCollection mc = reg.Matches(html);

            foreach (Match m in mc)
            {
                var url = m.Groups["url"].Value;

                if (url == "#")
                    continue;

                //相对路径转换为绝对路径
                Uri uri = new Uri(baseUri, url);

                //剔除外网链接(获取顶级域名)
                if (!uri.Host.EndsWith(baseHost))
                    continue;

                if (!visited.Contains(uri.ToString()))
                {
                    todo.Enqueue(uri.ToString());
                }
            }
        }
    }
}

 

当然还有很多优化的地方,既然是开篇也就这样了,快速入门才是第一位。

时间: 2024-10-28 11:03:26

玩玩小爬虫——入门的相关文章

玩玩小爬虫——抓取动态页面

       在ajax横行的年代,很多网页的内容都是动态加载的,而我们的小爬虫抓取的仅仅是web服务器返回给我们的html,这其中就 跳过了js加载的部分,也就是说爬虫抓取的网页是残缺的,不完整的,下面可以看下博客园首页 从首页加载中我们看到,在页面呈现后,还会有5个ajax异步请求,在默认的情况下,爬虫是抓取不到这些ajax生成的内容的, 这时候要想获取就必须调用浏览器的内核引擎来下载这些动态页面,目前内核引擎三足鼎立. Trident: 也就是IE内核,WebBrowser就是基于该内核,

玩玩小爬虫——试搭小架构

     第一篇我们做了一个简单的页面广度优先来抓取url,很显然缺点有很多,第一:数据结构都是基于内存的,第二:单线程抓取 速度太慢,在实际开发中肯定不会这么做的,起码得要有序列化到硬盘的机制,对于整个爬虫架构来说,构建好爬虫队列相当重要.      先上一幅我自己构思的架构图,不是很完善,算是一个雏形吧. 一:TODO队列和Visited集合      在众多的nosql数据库中,mongodb还是很不错的,这里也就选择它了,做集群,做分片轻而易举. 二:中央处理器      群架,斗殴都是

玩玩小爬虫——抓取时的几个小细节

      这一篇我们聊聊在页面抓取时应该注意到的几个问题. 一:网页更新      我们知道,一般网页中的信息是不断翻新的,这也要求我们定期的去抓这些新信息,但是这个"定期"该怎么理解,也就是多长时间需要 抓一次该页面,其实这个定期也就是页面缓存时间,在页面的缓存时间内我们再次抓取该网页是没有必要的,反而给人家服务器造成压力. 就比如说我要抓取博客园首页,首先清空页面缓存, 从Last-Modified到Expires,我们可以看到,博客园的缓存时间是2分钟,而且我还能看到当前的服务

python爬虫入门教程之点点美女图片爬虫代码分享_python

继续鼓捣爬虫,今天贴出一个代码,爬取点点网「美女」标签下的图片,原图. # -*- coding: utf-8 -*- #--------------------------------------- # 程序:点点美女图片爬虫 # 版本:0.2 # 作者:zippera # 日期:2013-07-26 # 语言:Python 2.7 # 说明:能设置下载的页数 #--------------------------------------- import urllib2 import urll

Python爬虫入门一之综述

大家好哈,最近博主在学习Python,学习期间也遇到一些问题,获得了一些经验,在此将自己的学习系统地整理下来,如果大家有兴趣学习爬虫的话,可以将这些文章作为参考,也欢迎大家一共分享学习经验. Python版本:2.7,Python 3请另寻其他博文. 首先爬虫是什么? 网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本. 根据我的经验,要学习Python爬虫,我们要学习的共有以下几点: Python基础知

node.js实现博客小爬虫的实例代码_node.js

前言 爬虫,是一种自动获取网页内容的程序.是搜索引擎的重要组成部分,因此搜索引擎优化很大程度上就是针对爬虫而做出的优化. 这篇文章介绍的是利用node.js实现博客小爬虫,核心的注释我都标注好了,可以自行理解,只需修改url和按照要趴的博客内部dom构造改一下filterchapters和filterchapters1就行了! 下面话不多说,直接来看实例代码 var http=require('http'); var Promise=require('Bluebird'); var cheeri

详解Java豆瓣电影爬虫——小爬虫成长记(附源码)_java

以前也用过爬虫,比如使用nutch爬取指定种子,基于爬到的数据做搜索,还大致看过一些源码.当然,nutch对于爬虫考虑的是十分全面和细致的.每当看到屏幕上唰唰过去的爬取到的网页信息以及处理信息的时候,总感觉这很黑科技.正好这次借助梳理Spring MVC的机会,想自己弄个小爬虫,简单没关系,有些小bug也无所谓,我需要的只是一个能针对某个种子网站能爬取我想要的信息就可以了.有Exception就去解决,可能是一些API使用不当,也可能是遇到了http请求状态异常,又或是数据库读写有问题,就是在这

Java编程技巧:小爬虫程序

本文介绍Java编程技巧之小爬虫程序的编程方法.   马萨玛索(http://www.masamaso.com/index.shtml)每天10点都会推出一折商品5件,就是秒购.男装质量还不错,所以就经常去抢,感觉手动太慢了,就写了一个小爬虫程序,让自己去爬,如果是金子页面(免费商品)就会自动打开,我就可以抢到了.和大家分享一下.   思路:   1. 把所有想要的商品的链接读到程序中.   2. 分别打开每一个链接读取源代码   3. 验证是否是金子商品(源代码中含有free_msg字符串)

【Python数据挖掘课程】一.环境配置及数据挖掘与爬虫入门普及

        最近因为需要给大数据金融学院的学生讲解<Python数据挖掘及大数据分析>的课程,所以在这里,我将结合自己的上课内容,详细讲解每个步骤.作为助教,我更希望这门课程以实战为主,同时按小组划分学生,每个小组最后都提交一个基于Python的数据挖掘及大数据分析相关的成果.但是前面这节课没有在机房上,所以我在CSDN也将开设一个专栏,用于对该课程的补充.        希望该文章对你有所帮助,尤其是对大数据或数据挖掘的初学者,很开心和夏博.小民一起分享该课程,上课的感觉真的挺不错的,挺