如何使用.Net来设计一个爬虫系统

创业以来尝试过好几个创业项目,在每次 bootstrap的时候,往往都需要借助于一些Internet上的内容,这里不可避免的就需要写一些简单的爬虫来抓取一些数据来完成项目的初期引导。这些小的爬虫对于我学习.Net,Http Protocol, Framework Design, Design Patterns提供了很多的帮助。爬虫版本的一次一次refactoring和upgrade都往往能够加深我对于某些领域的知识的掌握。

Open source方面比较有名的爬虫项目有Nutch和Heritrix。Nutch可谓出身名门,Lucene,  Hadoop,  Hbase等都给Nutch增色不少。Heritrix配置有点麻烦,我下载过source code,不过只是大概过了一下,没有具体debug它的具体源代码。前几天也看到园子里arrowcat和Phinecos(洞庭散人)两位同志做过一点介绍。由于个人是没有这方面深入的需求,所以一直都是靠自己个人来思考如何完成一个简单爬虫的设计和编码。这两个项目都是Java写的,所以对我们很多.Net fans来说还是不大方便。为此,我把我在写爬虫过程中遇到问题,solutions特别是一些需求总结给大家做些基本的介绍,希望对一些人有所帮助,对我个人也算是一个不错的总结。

第一,请求发送。一般我写的爬虫都是走http协议的,当然你可以用TCP协议来模拟http request。

· http request 发送和response接受

在.Net Framework中HttpWebRequest和HttpWebResponse两个类的封装使得http发送变得很容易,不过这两个类设计到很多http protocol方面的知识,所以不熟悉的同志还需深入挖一挖。一般都要提供GET和POST两个方法。这里可能会出现gzip压缩的解压,有些网站对于useragent要求不能为空等问题。

· 网站编码方式

我们常见的编码方式一般是UTF-8,GBK或者GB2312编码,这里如果网站变化多就需要自动检测出每个网站的编码方式,不然编码搞错了,后果很严重。这个我没有做过,应该拿一个request的响应然后分析一下那个结果的http header就可以确定出来了。如果网站可以简单枚举,自己手工设置一下就可以了。

· Request发送频率

如果你的request太多,容易给对方机器加大负载,可能会被server上某些软件屏蔽掉,最夸张会让对方管理员发现,所以要小心设置一个合适的请求延迟。不知道google的spider的参数怎么得来的,应该也是经验的慢慢积累来着。

· Http分析 :很多时候你写spider之前是需要分析一下爬虫源头,这里你需要借助一下工具来完成任务,我常用的是HttpWatch,Fiddler2, IE Developer Toolbar, FireBug,类似还有一些,例如Microsoft Network Monitor, Web Development Helper等。有了这些工具的帮助使得你能够快速了解要抓网页的结构和request的一些细节。

第二,内容解析。通过request我们拿到response后就需要根据其内容的格式进行解析。我以前写过关于hotmail, gmail, yahoo! Mail, 163的联系人导入程序,这些可能需要你去解析xml, json等格式。还有一个关于blog的rss解析问题,这里都有一些规则,如果能找到open source的library最好,没有只好读点文档或者研究其规则自己尝试解析了。对于xml解析,使用SAX要比DOM快很多。RSS+ATOM可能有.net方面的开源类库,我以前是自己解析的,这个就很难把所有情形cover了,risk还是蛮高的。对于最常见的Html解析您可以选用htmlparser这样的类库,当然也可以自己从头来,我主要是利用正则表达式和.Net Framework来搞定这些问题的,例如从文档中抽取出所有的html anchors,去除所有的html tags,变相对路径url成绝对路径url,截取一部分内容到一句话结尾等。还有可能遇到的情形就是垂直搜索,例如抓电影信息,可能对导演,演员,播放长度,图片要求很准确,这里你的spider extractor就需要依赖对方的html格式,如果对方有rss等API那就爽了。没有你只能想办法降低对html格式的依赖程度了,也可能需要提供一些解析器失效的报警或日志机制。

列一下可能需要的代码:

抽取所有链接:

Regex htmlLinkReg = new Regex(@"(href)[ ]*=[ ]*[""'][^""'> ]+[""'> ]", RegexOptions.IgnoreCase);

去除html标签和 这样的编码:

result = Regex.Replace(html, @"<(.[^>]*)>?", replacedWord, RegexOptions.IgnoreCase);
  
result = Regex.Replace(result, @"&\w{2,7};", "");

第三,分布式的架构。这里可能涉及到多客户端的部署,因为很多时候IP算是稀有资源,同一个IP来抓速度还是很慢的,又不敢太快。呵呵。我写过一个分布式爬虫,抓了数千万数据下来。Client我一般是用winform写的,后台开点线程来完成各种爬行任务,它每次从服务器获取一点任务,然后去发送request,解析结果,最后再通过http request来上传爬行结果。这种简单的架构还是很容易scale的。

· 爬行历史:你可能需要将spider的url爬行历史记录保存下来,一方面可以避免重复爬行;另外也可以判断这些url是否在上次爬行后更新过。

· 网站更新:如果您需要持续抓取某个网站的内容,你可能需要把首页或者更新相关的页面作为源头,然后抽取出页面所有链接,然后filter出你要解析的页面和已经爬过的页面,然后使用一个队列来存储这些源头,通过进一步加深爬虫深度来找到所有可能新的内容页面,这里你可以使用广度优先搜索或者DFS来递归深入。这里你可能会遇到输入输出速率不匹配的情形,你可能需要依赖一些队列模拟,当然也可以自己通过数据库来实现。

· 具体页面爬行:如果您通过数据库等来存储具体内容页面的源头,对于分布式的应用,你可能需要考虑好同步问题,你可以依赖于.Net提供的一些concurrency方法来解决可能的并发重复问题,例如Monitor, Semaphore, Event, Mutex等.

以上几点是我关于一个简单爬虫设计可能遇到的问题的总结。希望对于需要的有所帮助。

时间: 2024-10-21 20:01:19

如何使用.Net来设计一个爬虫系统的相关文章

如何设计一个RPC系统

RPC是一种方便的网络通信编程模型,由于和编程语言的高度结合,大大减少了处理网络数据的复杂度,让代码可读性也有可观的提高.但是RPC本身的构成却比较复杂,由于受到编程语言.网络模型.使用习惯的约束,有大量的妥协和取舍之处.本文就是通过分析几种流行的RPC实现案例,提供大家在设计RPC系统时的参考. 由于RPC底层的网络开发一般和具体使用环境有关,而编程实现手段也非常多样化,但不影响使用者,因此本文基本涉及如何实现一个RPC系统. 认识RPC(远程调用) 我们在各种操作系统.编程语言生态圈中,多少

如何设计一个秒杀系统

什么是秒杀 秒杀场景一般会在电商网站举行一些活动或者节假日在12306网站上抢票时遇到.对于电商网站中一些稀缺或者特价商品,电商网站一般会在约定时间点对其进行限量销售,因为这些商品的特殊性,会吸引大量用户前来抢购,并且会在约定的时间点同时在秒杀页面进行抢购. 秒杀系统场景特点 秒杀时大量用户会在同一时间同时进行抢购,网站瞬时访问流量激增. 秒杀一般是访问请求数量远远大于库存数量,只有少部分用户能够秒杀成功. 秒杀业务流程比较简单,一般就是下订单减库存. 秒杀架构设计理念 限流: 鉴于只有少部分用

如何设计一个复杂的分布式爬虫系统?

一个复杂的分布式爬虫系统由很多的模块组成,每个模块是一个独立的服务(SOA架构),所有的服务都注册到Zookeeper来统一管理和便于线上扩展.模块之间通过thrift(或是protobuf,或是soup,或是json,等)协议来交互和通讯. Zookeeper负责管理系统中的所有服务,简单的配置信息的同步,同一服务的不同拷贝之间的负载均衡.它还有一个好处是可以实现服务模块的热插拔. URLManager是爬虫系统的核心.负责URL的重要性排序,分发,调度,任务分配.单个的爬虫完成一批URL的爬

【译】系统设计入门之面试题解答 —— 设计一个网页爬虫

本文讲的是[译]系统设计入门之面试题解答 -- 设计一个网页爬虫, 原文地址:Design a web crawler 原文作者:Donne Martin 译文出自:掘金翻译计划 译者:吃土小2叉 校对者:lsvih 设计一个网页爬虫 注意:这个文档中的链接会直接指向系统设计主题索引中的有关部分,以避免重复的内容.你可以参考链接的相关内容,来了解其总的要点.方案的权衡取舍以及可选的替代方案. 第一步:简述用例与约束条件 把所有需要的东西聚集在一起,审视问题.不停的提问,以至于我们可以明确使用场景

百度研发笔试题解析:设计一个系统处理词语搭配问题

题目: 设计一个系统处理词语搭配问题,比如说 中国 和人民可以搭配,则中国人民 人民中国都有效.要求: *系统每秒的查询数量可能上千次: *词语的数量级为10W: *每个词至多可以与1W个词搭配 当用户输入中国人民的时候,要求返回与这个搭配词组相关的信息. 分析: 性能要求:每秒查询量达到上千次,意思就是QPS要达到1000以上. 搜索端使用多线程处理,现在服务器都是多核的,可以充分利用服务的资源. 数据结构: 所有词语建一张大表,并给每个词语分配一个id. 存储结构如下: id1,word1,

一个购物系统的数据库订单表该如何设计

问题描述 一个购物系统的数据库订单表该如何设计 订单中要显示购买者信息,购买者配送地址,商品名,价格,数量其中商品可能是多个. 解决方案 这个最好是设计2个表,,一个订单,,一个订单详情,,订单中是用户的信息与购买的商品名,,订单详情中是商品的具体价格,数量,介绍等信息 解决方案二: 一张用户信息表,一张订单详情表,用户信息表唯一,主键是订单详情表的外键

如何设计一个高性能的日志系统

问题描述 如何设计一个高性能的日志系统 需求: 1.系统采用B/S架构,要求能够记录客户端的任何事件,比如单击了某个按钮或者链接: 2.要求能够记录用户每次操作时后台代码使用到的SQL和参数,比如添加数据时的SQL语句和具体的Parameter: 3.将1和2串联或者合并起来,意思就是我在分析日志时,能够在查询客户端事件时也能看到后台的SQL语句和参数: 4.2年内数据达到20亿条记录,采用什么样的数据库比较合适,非关系行的MongoDB还是关系型的Oracle: 解决方案 4.什么数据库都没关

设计一个论文提交评价系统,怎样管理各种角色

问题描述 设计一个论文提交评价系统,怎样管理各种角色登陆,记录登陆后各个页面的登陆者角色,以及登陆后访问的权限就是角色管理的入门级问题,麻烦各位高手帮忙详细解释一下实用的解决方案 解决方案 解决方案二:设置userType属性,每个页面进入跟操作前都验证该用户是否有操作权限一般简单点的话用session解决方案三:做一个权限管理系统吧角色表里面放网站的权限名称如管理员超级管理员资源表资源的名称,页面如果作业查看aaa.aspx权限对应的表角色ID资源ID能进行的操作比如浏览,修改,删除这样能把权

设计一个智能客服系统

背景: 最近在设计一个公司的智能客服系统,通过对现有人工客服语料作为样本,通过训练样本完成整个QA过程或业务办理过程. 整体思路 AliceBot负责闲聊,这里用了开源的语料,也可以添加语料到DB,基于AIML. AbilityBot主要负责公司业务上的咨询和办理,它提供了不同的能力接口,供外系统交互. predict模块用于预测响应. train模块用于训练客服对话样本. 语音转换 由第三方语音识别服务提供转换成文本,比如讯飞. 语义处理 由于机器本来是无法理解文本的含义的,如果要真正做到语义