网络爬虫的实现思路
来源:互联网 发布:数据挖掘工程师年薪 编辑:程序博客网 时间:2024/06/05 15:02
网络爬虫
一般我们在网络上抓取数据时,都会想到要使用网络爬虫,那我们就来看看一般网络爬虫的实现思路。
设计模式
爬虫的中心思想就是以最初一个Url为注入点,从这个Url抓取更多Url,并从这些网页中获取自己想要的数据。所以,我们可以使用一个队列来存储这些Url,然后使用 生产者消费者模式来对这个队列进行维护。
Queue<string> urlQueue=new Queue<string>();public void AddUrl(string url){ lock(this) { urlQueue.Enqueue(url); }}public string GetUrl(){ lock(this) { string url=""; if(urlQueue.Count>0) { url=urlQueue.Dequeue(); } return url; }}
使用多线程能够更有效率的抓取数据,但是容易互相抢资源,所以要上锁。
目前我想到的多线程模式有两种,一种是 spider从队列中获取一个Url,然后从对应的网页获取其他Url和数据。另一种是分成专门生产Url的spider和专门从网页中抓取数据的spider。这里选第一种举例。
我们可以使用一个SpiderManager来管理所有的Spider,每一个Spider专门开一条线程来工作。
public class SpiderManager{ List<Spider> spiders; Queue<string> urlQueue=new Queue<string>(); public void AddUrl(string url) { lock(this) { urlQueue.Enqueue(url); } } public string GetUrl() { lock(this) { string url=""; if(urlQueue.Count>0) { url=urlQueue.Dequeue(); } return url; } } public void Stop() { foreach(Spider spider in spiders) { spider.Stop(); } }}
public class Spider{ int restTime=1000;休眠间隔 Thread workingThread; SpiderManager spiderManager public Spider(SpiderManager sm) { this.spiderManager=sm; } pubclic void Start() { workingThread=new Thread(Work); workingThread.Start(); } private void Work() { while(true) { string url=sm.GetUrl(); if(url=="") { Sleep(restTime); Continue; } //抓取数据 } } public void Stop() { if(workingThread!=null) { workingThread.Abort(); workingThread=null; } }}
URL查重
一般来说我们不想重复的抓取同一张网页,这个时候就需要查重技术了。
我们可能会使用hash表来存储对应的url,这的确能够解决一部分问题。但如果我们要抓取的数据量非常大的话,hash表就满足不了我们的需求了,这个时候我们就可以使用布隆过滤器来进行查重。
布隆过滤器(Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的。它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Filter报告某一元素存在于某集合中,但是实际上该元素并不在集合中)和删除困难,但是没有识别错误的情形(即假反例False negatives,如果某个元素确实没有在该集合中,那么Bloom Filter 是不会报告该元素存在于集合中的,所以不会漏报)。
布隆过滤器实际上一个很长的二进制和随机映射函数。首先,将这个二进制中的数据全设为0,然后将我们url使用随机映射函数映射到这个二进制中的随即八个位置,将他们设为1。如果要查看url是否重复,可以就可以查看对应的位置是否均为1。这样就能节省非常多的空间,对于5000w级的url,只占用200mb的空间,缺点是有可能会误判。不过误判的几率非常低,如果在意的话可以建立白名单来补救。
优化
如果我们进行大量并发的抓取数据的话,可能在一条队列中会阻塞很久,我们可以多开几条队列,并使用标志位来分流。
如果抓取大量数据的话,可能还会使用分布式的架构来抓取,那分布式的话应该是怎样呢。分布式的话就需要考虑到不同机器之间的通信,以及容错。通信的话可以使用Socket来进行网络间的通信。
- 爬虫控制中心:控制整个爬虫系统
- 集群控制中心:控制整个集群,集群中的每个机器都和集群控制中心通信
集群中心将任务分派给不同机器,并且与机器进行心跳连接。如果机器连接超时,则认为机器宕机,将该机器上的任务取回分派给其他机器。
- 网络爬虫的实现思路
- 实现网络爬虫思路
- 网络爬虫的实现
- 网络爬虫的实现
- 网络爬虫的实现
- 网络爬虫的实现
- 网络爬虫的实现
- 网络爬虫思路
- Java网络爬虫的实现
- Java网络爬虫的实现
- JAVA网络爬虫的实现
- Java网络爬虫的实现
- Java网络爬虫的实现
- Java网络爬虫的实现
- Java网络爬虫的实现
- java网络爬虫的实现
- Java网络爬虫的实现
- Java网络爬虫的实现
- 第一周上机实验
- js与jquery 对表单值的操作,有些区别不注意还真会混淆
- iOS运用runtime全局修改UILabel的默认字体
- assign©&ratain, strong&weak, nonatomic
- 利用.htaccess绑定子域名到子目录
- 网络爬虫的实现思路
- 压缩任意多层的文件夹 Java代码实现
- 竖排的选项卡
- c++第一次实验
- iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接)
- C# 类型基础 值类型和引用类型
- Google推荐的图片加载库Glide介绍
- 动态内存
- 【POJ 2296】 Ring 中文题意&题解&代码(C++)