如何用最小的代价完成爬虫需求

标签: WEB安全 爬虫 | 发表时间:2017-04-02 12:17 | 作者:岂安科技
出处:http://www.freebuf.com

1.jpg 

一  缘起

在我工作的多家公司,有众多的领域,如房产,电商,广告等领域。尽管业务相差很大,但都涉及到爬虫领域。开发爬虫项目多了后,自然而然的会面对一个问题——

l 这些开发的爬虫项目有通用性吗?

l 有没有可能花费较小的代价完成一个新的爬虫需求?

l 在维护运营过程中,是否能够工具化,构建基于配置化的分布式爬虫应用?

这就是是我们今天要讨论的话题。

二  项目需求

立项之初,我们从使用的脚度试着提几个需求。

1. 分布式抓取

由于抓取量可能非常庞大,一台机器不足以处理百万以上的抓取任务,因此分布式爬虫应用是首当其冲要面对并解决的问题。

2. 模块化,轻量

我们将爬虫应用分成“应用层,服务层,业务处理层,调度层” 四个脚色。

3. 可管理,可监控

管理监控是一个体系,即配置可管理化,运行实时监控化。在系统正常运行时,可以变更爬虫的配置,一旦实时监控爬虫出现异常,可实时修正配置进行干预。所有的一切,均可以通过UI界面进行操作。

4. 通用性,可扩展。

爬虫业务往往多变,不同领域的爬取需求不尽相同。举例说,房源抓取包含图片抓取,小区信息抓取,房源去重等模块。新闻抓取包括内容抓取,正文提取,信息摘要等相关。

因此,系统需要能够支持业务扩展需求,可以支持不同的业务使用同一套框架进行应用开发。 

三  模块分解

针对业务需求,我们将系统分解成多个应用模块。

应用层

应用层是针对管理员,系统维护人员使用。主要分成两个模块,系统配置模块和运营管理模块。

l 系统配置模块:系统配置模块包含抓取网站管理配置,在线测试等功能。

l 运营管理模块:运营管理模块包含实时抓取量统计,分析,正确率等。甚至包括失败原因,失败量。

系统运营人员可以根据运营模块得到实时的反馈,使用系统配置模块进行配置修正,在线测试正确后将配置生效,再实时监控新的配置产生的效果。

服务层

服务层是整个系统传输的中枢,相当于整个分布式集中的系统总线和数据总线。服务层提供一个http/thrift接口,读取数据库,输出配置信息。

a. 提供网站爬虫配置接口。从数据库中实时读取配置信息,响应业务层的配置请求。

b. 提供业务层输出写入接口。接受业务层实时爬取的信息汇总,包括正确数据量,错误数据量,以及错误原因。

c. 提供实时报表统计分析。响应应用层的运营管理模块,查询数据库,实时提供数据分析报告。

业务处理层

业务处理层是整个爬虫系统的核心,可分成多台应用服务器进行处理。业务处理层主要包含解决两件事情。

l 如何获取url

l 得到url后,如何处理

(一)  如何获取url

对于爬虫来说,如何获取url至关重要。我们将这一过程定义为发现系统。对于发现系统而言,目标为如何发现待抓取网站的详细url列表,尽可能的发现更全。

假设场景 A

我们逛一个电商网站:打开首页-打开分类页-可能会有多层分类页-逐层点击-直至最小的分类页面。

打开这个分类页会发现该分类页下的所有分页页面,一页一页往下翻,就能够获得该分类页的所有商品。

假设场景 B

我们逛一个汽车网站:打开首页-找到品牌页-接着找到车系-最后找到车款页面。

通过以上场景分析可以得到一个结论,人能非常智能的找到所有待抓取的详细页面,即电商的商品,汽车的车款页面。那么,是否可以通过配置方式来模拟这一过程呢?

请看下图:

2.jpg

备注如下:

1. root_info:

定义发现模块的入口页面,如同人打开汽车站的网页,后续的发现都是起始于这些入口页。

这里给出的实例是,某汽车网的品牌列表页,根据“模板化”套用变量的配置,共有100个入口页。

2. steps: 

依次遍历这100个入口页,分别会执行steps中定义的步骤。机器模拟人的方式进行查看浏览。

每个step中,会使用”link_module”定义的类进行逻辑进行处理。

a. 读取入口页的html,结合”sub_prefix”,”sub_suffix”和”select”定义的内容,获得页面子区域html。

b. 使用”link_match_method”的方法(含前缀包含,匹配等),抽取子区域的链接。

c. 每个链接 和”link_pattern”进行匹配,匹配成功的url进入下一步。

d. 每一步得到的url,自动进和地下一步处理,处理逻辑为递归上面a-c,直至”last_step”为true为止。

此处,即”last_step”为true中发现的url,即为发现系统最终需要获取的url列表。发现系统总结,通过配置的方式,结合人类的浏览习惯,通过若干步迭代,最终获取网站的详细页url列表。

由于每一步的抽取链接规则,以及步数据都是人为定义,因此,可以适配绝大部分网站的发现系统。当然,越复杂的网站发现配置可能更多一些、更为繁杂,但万变不离其宗。

(二)得到url后,如何处理

前提当然是每个业务的处理各不相同,有抽取页面属性功能、有正文提取、有图片获取,甚至有和当前系统对接等。

由于业务处理不一致,很自然想到的是通过配置方式,定义职责链系统,如同著名框架Netty中的Pipeline设计。在处理过程中,定义一个Context上下文处理类,并且,所有的中间结果都暂缓在这个Context中。

描述比较空洞,还是结合实际案例来看。

3.jpg

备注如下:

得到一个url后,读取配置,当url和”site”匹配时,适用当前”site”规则。

1.  pipeline定义职责链的处理过程

此处的定义为“抓取模块,Javascript处理模块,通用解析模块”。对应的处理如下:

先执行抓取模块,得到html。紧接着执行Javascript处理模块,输入为html,解析html,此处可能是评论,也可能是价格,总之处理的是动态加载项目,紧接着处理“通用解析模块”

2.  ”parser_rules”定义的是解析模块

最终输出的是kv,在java中是map,python中是dict。即从上一步的html中,找到每一荐的”sizzle”,执行”prefix”,”suffix”即前后缀移除(过滤如同“价格:xxx元,前缀为“价格:”,后缀为元)。

对了,sizzle也是一个开源技术,据说以前鼎鼎有名的Jquery也是”sizzle”引擎。Java中可以使用Jsoup解析处理。

怎么知道需要取的”sizzle”内容是什么呢?具体可以结合firebug插件,选中即可得。选中后,结合应用层的管理工具,即可进行测试。

3. “isrequire”

可以看到,配置项中有“isrequire”,表示这项内容是否必须。如果必须,且在实际处理中获取不到,那么在抓取的过程中,就会记录一个错误, 错误原因自然是“$key is null”。此外,每一个module都可能出错,一旦出错,就没有必要往后去执行。

因此,在抓取过程中,业务处理层从服务层获得一批url(默认100个)后,在处理这一百个url结束后,会向服层report,report内容为:

当前任务处理机器,于什么时间处理100个页面。不同网站成功多少、失败多少、什么模块失败多少,解析模块什么字段失败多少。

所有这些信息,均是实时统计,并在运营监控系统中以图表形示绘制出来,必要时可以发出报警,交由维护人员实时干预。

Q: 提一个问题,新增一个anotherauto.com网站怎么办?

A: 其实也很简单,再增加一个配置呗。业务定义pipeline,如果有解析需求,填写对应的解析项即可。

以上两个系统,发现系统和处理系统,在我们实际生产中,是通过以下步骤贯穿。

a. 发现系统累计发现待抓取网站的详细页,因为是一个累计持续的过程。因此有把握持续无限接近网站的100%页面。

b. 处理系统通过服务层,每次去取配置信息(可能维护人员在实时修正)及待抓取的列表进行处理。

待抓取的列表根据业务的优先级,分普通队列及优先级队列,通过任务调度系统进行统一管理和配置。

调度层

l 调度层主要是业务系统。

l 新增一个网站任务调度

l 网站发现频率,包括增量发现频率和全量发现频率

l 网站抓取优先级推送至队列

l 断点续抓管理

l ……

四  系统架构设计

l 从业务模块上看

应用层,服务层,业务处理层,调度层

l 从功能系统上看

发现系统,抓取系统, 配置系统,监控系统

l 从扩展性上看

自定义职责链,自定义属性提取

l 从实时性上看

实时抓取,实时配置生效,实时监控,实时测试

l 从系统架构上看

分布式架构,服务层主从切换设计,轻量(仅依赖于队列,数据库,java)

五  图例

① 

4.jpg

② 

5.jpg

③ 

6.jpg

爬虫模块 ui二 (1.6  任务配置) :

定义每个爬虫任务的处理执行职责链,不同的爬虫任务可以有不同的处理链。对于系统而言,处理每一个待爬取的url,都会按照职责链的顺序执行。后置处理类则是一批任务执行后(如上文的100个url),批量提交的方式。如文件落地,入库,推往线上系统等。通过任务处理定义,则可以自定义各类不同场景的爬虫业务,在不编码的前提下增加系统的灵活性。

④ ​

7.jpg

属性配置:

如图所示,维护人员增加条测试的url,同时定义需要提取的属性,则可在线定义该页面对应的属性输出,可见即可得。
在增加便利性,可测试性的基础上,又能灵活的选取页面的任意属性,值得一提的是,可以通过firefox插件获取sizzle的配置。

⑤ 

8.jpg

1.9查看明细:


在爬虫系统的运行过程中,几乎可以实时的进行任务的监控。由于爬虫任务实时将爬取的状态写入数据库,因此完全可以通过ui界面进行管理及监控。1. 监控:监控爬虫任务当前时间成功次数,错误次数,什么模块错误,甚至某个属性提取错误。2. 管理:维护人员观测监控效果后,可实时进行编辑及管理(见上一张图),以应对不同网站的改版需求。所有编辑实时生效,编辑完成后,无需重启服务,又可实时监控爬虫任务的最新效果。

踏浪无痕  岂安科技高级架构师 

十余年数据研发经验,擅长数据处理领域工作,如爬虫、搜索引擎、大数据应用高并发等。担任过架构师,研发经理等岗位。曾主导开发过大型爬虫,搜索引擎及大数据广告DMP系统目前负责岂安科技数据平台开发与搭建。

*本文作者:岂安科技,转载请注明来自Freebuf.COM

相关 [爬虫 需求] 推荐:

如何用最小的代价完成爬虫需求

- - FreeBuf.COM | 关注黑客与极客
在我工作的多家公司,有众多的领域,如房产,电商,广告等领域. 尽管业务相差很大,但都涉及到爬虫领域. 开发爬虫项目多了后,自然而然的会面对一个问题——. l 这些开发的爬虫项目有通用性吗. l 有没有可能花费较小的代价完成一个新的爬虫需求. l 在维护运营过程中,是否能够工具化,构建基于配置化的分布式爬虫应用.

网络爬虫

- - 四火的唠叨
文章系本人原创,转载请保持完整性并注明出自 《四火的唠叨》. 最近在写一个程序,去爬热门事件和热门关键词网站上的数据. 网络爬虫也叫做网络蜘蛛,是一种互联网机器人,把需要的网页撷取下来,组织成适当格式存储. 它是搜索引擎的重要组成部分,虽然从技术实现上来说,它的难度往往要小于对于得到的网页信息的处理.

Google 图片爬虫

- - 吴良超的学习笔记
这里的 Google 图片爬虫指的是爬取在 Google 上通过关键词搜索得到的图片,由于最近需要一些特定领域的图片,而且现有的数据库满足不了要求,因此就想通过 Google 搜索筛选出这些特定领域的图片,然后下载下来后再进行人工筛选. 这里采用了两种方法,区别在于是否需要解析网页端的 JS 代码.

JSOUP实现简单爬虫

- - ITeye博客
这个说是简单爬虫 其实连个爬虫也算不上吧 功能太精简了.... 流程很简单: 输入几个初始的网页 然后通过JSOUP获取网页中的a标签的href的值. 接着把新得到的地址放入任务队列中. 实现中的worker是一个单线程的派发器 用于产生Parser. Parser用于完成网页的保存 网页的解析 以及入队列操作.

最全Python爬虫总结

- - CSDN博客综合推荐文章
最近总是要爬取一些东西,索性就把Python爬虫的相关内容都总结起来了,自己多动手还是好. (2)保存爬取的图片/视频和文件和网页. (7)某个网站的站内所有目录爬虫. (9)爬虫框架Scrapy   . 二,保存爬取的图片/视频和文件和网页. #图片/视频和文件和网页的地址抓取下来后,利用模块urllib里的urlretrieve()方法下载下来:.

htmlunit爬虫优化方案

- - 研发管理 - ITeye博客
发现很多人搞爬虫会把python作为首选技术,理由是简单;但是本人最熟悉的还是java,所以对java内存浏览器技术htmlunit做了一次研究,发现原生的htmlunit的性能及对多线程的支持不是那么友好,特别是使用代理ip后,oom是很正常的,监控程序并查看源码总结问题原因:. 1、js执行器执行js是使用多线程执行,在关闭js执行线程的时候,使用com.gargoylesoftware.htmlunit.javascript.background.DefaultJavaScriptExecutor这个类的时候,有段代码.

爬虫需谨慎!那些你不知道的爬虫反爬虫套路 学起来

- - IT瘾-bigdata
爬虫与反爬虫,是一个很不阳光的行业. 第一是,这个行业是隐藏在地下的,一般很少被曝光出来. 很多公司对外都不会宣称自己有爬虫团队,甚至隐瞒自己有反爬虫团队的事实. 这可能是出于公司战略角度来看的,与技术无关. 第二是,这个行业并不是一个很积极向上的行业. 很多人在这个行业摸爬滚打了多年,积攒了大量的经验,但是悲哀的发现,这些经验很难兑换成闪光的简历.

Scrapy爬虫笔记【1-基本框架】

- - CSDN博客研发管理推荐文章
Scrapy 是一款抓取网页并从中提取结构化数据的应用程序框架,它具有非常广泛的应用场景,如:数据挖掘、信息处理和历史信息归档等. 尽管 Scrapy 最初被设计用于 屏幕抓取(准确地说是 网页抓取),但您也可以仅使用它的 API 来提取数据(就像. Amazon Associates Web Services)或作为通用的网页爬虫来使用.

JAVA爬虫Nutch、WebCollector的正则约束

- - CSDN博客互联网推荐文章
爬虫爬取时,需要约束爬取的范围. 基本所有的爬虫都是通过正则表达式来完成这个约束. 代表"http://www.xinhuanet.com/"后加任意个任意字符(可以是0个). 通过这个正则可以约束爬虫的爬取范围,但是这个正则并不是表示爬取新华网所有的网页. 新华网并不是只有www.xinhuanet.com这一个域名,还有很多子域名,类似:news.xinhuanet.com.

Python写爬虫与网页解析

- - 互联网实践
Python写个简单爬虫,并作网页解析,还是非常高效的. urllib2是urllib得增强版,httplib更为底层,可以理解为urllib是对httplib的抽象. httplib是一个相对底层的http请求模块,其上有专门的包装模块,如urllib内建模块,goto等第三方模块,但是封装的越高就越不灵活,比如urllib模块里请求错误时就不会返回结果页的内容,只有头信息,对于某些需要检测错误请求返回值的场景就不适用,所以就得用这个模块了.