博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
玩玩小爬虫——入门
阅读量:7039 次
发布时间:2019-06-28

本文共 2671 字,大约阅读时间需要 8 分钟。

   前段时间做一个产品,盈利方式也就是卖数据给用户,用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;        ///         /// 工作队列        ///         public static Queue
todo = new Queue
(); //已访问的队列 public static HashSet
visited = new HashSet
(); 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()); } } ///
/// 提取Url /// ///
public void RefineUrl(string html) { Regex reg = new Regex(@"(?is)
]*?href=(['""]?)(?
[^'""\s>]+)\1[^>]*>(?
(?:(?!
"); 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()); } } } }}

 

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

转载地址:http://neial.baihongyu.com/

你可能感兴趣的文章
Python 网络编程socket_server单线程响应请求
查看>>
ogre的材质与unity的材质的相似性
查看>>
当我们老了的时候 或许签名和状态会这样写
查看>>
maven 生命周期
查看>>
AngularJS API之equal比较对象
查看>>
I'm Coming
查看>>
apicloud开发混合app实战二手车项目
查看>>
c语言指针运算符和取地址运算符的简单运用
查看>>
popuWindow 要求onClick和onTouch 事件 不起作用
查看>>
mvn 常用命令
查看>>
常用windows命令行
查看>>
android在线API地址
查看>>
Android APK反编译详解
查看>>
Codeforces goodbye 2014 a
查看>>
Actor, Reactor与Proactor模型
查看>>
Verson Magic problem
查看>>
android 源码编译sdk(用于android应用开发)
查看>>
Android常用网址
查看>>
sbt解析spark依赖报错
查看>>
Hibernate的SQL执行顺序引发的血案
查看>>