搜索引擎数据采集
背景
随着互联网上的信息持续爆发式的增长,依靠人类的力量去收集和查找想要的信息已经越来越不可能实现,所以人们开始通过搜索引擎技术来帮助人们更快更准确的筛选和寻找自己所需要的信息。
痛点
互联网上的信息分布具有以下一些特点,其中任意一个都会对人类用户的信息搜寻带来很大的困扰
- 分布的范围广,动辄几百上千万的网站中都可能存在想要的信息
- 分布的位置零散,没有合适的索引能够帮助用户快速的找到想要的信息
- 内容良莠不齐,大量重复、错误、谬误等信息的存在,让用户很难判断所需内容的准确性
爬虫发展简史
- 上古时期:简单爬虫
上古时期没有那么多网站需要抓取,网站构建和维护的技术实力也较为原始,所以普通的能完成http访问的工具包配合简单的网页分析代码就可以完成。 - 中古时期:定制化页面解析
中古时期开发者开始有了一些版权和反爬意识,同时开始尝试通过不同的手段美化自己的页面,仅依靠简单通用的解析库已经不足以支持丰富多彩的页面加载、渲染方式了,所以需要针对不同的页面单独定制解析逻辑。 - 大航海时代:网页模板与工业化实践
随着网络用户的增长,个人和机构对网站/页这样的信息渠道的依赖也愈发紧密,web技术也从全栈逐渐向前后端分离的架构演进,网站的构建从过去八仙过海的方式逐渐演化为通用模板配合细微定制化升级,从小作坊式的迭代逐渐升级为工业化集群式的更新与升级 - 近代:制式工具
随着网站/页数据量的进一步增长,对网站/页内容的抓取需求也愈发强烈,爬虫从业者们也由过去的单兵作战逐渐成长为团队作战,随之而来的就是爬虫相关的框架等技术的蓬勃发展。 - 现代:分布式爬虫
现代的公司团队对数据的渴求愈发强烈,而互联网上直接可访问的网站/页又是最直接和廉价的数据来源,短时间大规模的数据采集倒逼爬虫团队从过去的单体服务进化成大规模分布式的机器人。
爬虫相关概念
爬虫协议
虽然爬虫方便了搜索引擎对开放数据进行收录,进而能够支持普通用户对信息的检索,但是有一些站点出于各种考虑不希望自己的页面被搜索引擎收录,爬虫协议就应运而生了。爬虫协议主要是一个爬虫业的一个约定俗成的约束,主要规定了对于某些爬虫,本站点中的某些路径的页面的一些权限。不过,既然是约定俗成的约束,就是个类似君子协定的存在,也会有爬虫的使用方无视这种协议进行数据的抓取,其中比较有名的如某条,某多等公司。
爬虫基础库
- 分布式框架,用来进行分布式多线程的对站点进行访问(下载)、分析、和保存
- 存储:
- 短期存储(如redis、memcache等)用来做系统状态跟踪、资源去重等
- 中期存储(如RDMS等)用来保存系统配置、解析模板等
- 长期存储(如OSS等)保存rawdata,作为基底数据,用来支持后续的数据需求
- 解析模板库,通过规定不同的解析模板来进行常规页面的解析和信息抽取
- 爬虫基础中库,如ip池、验证码识别库等工具库,用来突破反爬限制
- 消息队列:
- 在基础数据抽取和清洗之后,通过消息队列将数据抓取和后续的服务进行解耦
- 通过不同队列/topic等方式驱动通用爬虫worker将路径的抓取和内容的抓取进行解耦
反爬技术
现在比较流行的说法是流量为王,想要有流量就要有流量入口,而搜索引擎往往就扮演了流量入口这样一个角色,所以会衍生出SEO(Search Engine Optimizatio)、竞价排名等概念。信息的提供方在围绕着某些搜索引擎付出了时间、精力、资源进行运营之后,就会希望自己的高质量的内容能出现在相关的平台之中,同时也要尽量避免这些内容被其他平台“白嫖”;爬虫作为机械性的访问,往往能造成比人类用户大得多的流量,对于一些技术能力不足的个人/机构来说,大量的爬虫访问很可能会占满他们的服务器带宽,造成类似DDoS攻击的效果,同时,对于部署在云厂商的服务,往往是需要为服务的访问流量付费的,大量的爬虫(而非目标用户)流量也会带来不必要的带宽、运维等成本;除此之外,在一些站点中会有一些页面、站点也会有金钱、影响力等的作用,如秒杀茅台、抢优惠券、主播打榜等。
正是由于企业、站点存在这种既要又要还要的拧巴的需求,业界开发出了各种反爬技术。反爬技术和爬虫技术就像矛和盾的关系,爬虫技术希望可以更准确高效的抓取数据,但是反爬技术又希望提高爬虫抓取解析内容的代价。
常见的反爬技术有:
- user-agent限制:
- 盾:只接受/禁止某些特定的请求头
- 矛:模拟请求头
- 验证码:
- 盾:通过图形而非机器直接可见的字符进行过滤
- 矛:CV + ML 技术进行识别,付费的人工打码平台
- 滑块验证:
- 盾:不同于验证码的纯视觉校验,滑块验证还引入了用户交互行为的验证
- 矛:代码模拟用户行为
- IP 黑/白名单:
- 盾:禁止/允许某些特定IP/网段的访问
- 矛:IP 代理池
- 关联请求上下文:
- 盾:通过请求token等方式进行限制
- 矛:协议解析模拟,中间人攻击等
- JavaScript参与计算:
- 盾:页面初始化并不会加载全部内容,而是会随着一些页面交互出发后续内容的加载
- 矛:自带js引擎解析,模拟浏览器抓取
- 页面关键信息替换:
- 盾:如通过CSS重组页面元素位置,将文字内容替换成图片等
- 矛:页面代码分析,混淆算法逆运算等
信息去重
由于源信息的更新不会及时通知到爬虫方,爬虫只能定时/不定时的对目标地址进行信息抓取。由于信息可能会存在包括信息的复制、转发、修订、归档等操作,爬虫抓取到的信息可能会存在重复,而对重复信息的处理会浪费系统资源,所以爬虫运行时很重要的一部分是信息去重。
信息去重主要包含以下几个方向:
- url去重,对重复的源地址进行去重,爬虫只关心新内容的抓取,而跳过之前曾经处理过的地址
- 页面内容去重,对于不同地址但相似内容的信息进行分析,跳过后续复杂的数据清洗、解析的流程
- 信息深层去重,爬虫在实际运行时,可能会遇到针对热点事件、重要内容进行不同角度的撰写甚至洗稿,所以需要对内容的深层分析,不过大部分的数据抓的需求是不需要进行这一步的去重的
数据爬取流程
数据抓取
爬虫不同于人类用户,他们“看到”的网页信息为页面代码(保护html、css、js等),但是这些信息中真正有价值的可能只有文章的标题、作者、发布时间等内容,所以爬虫往往会在页面抓取和下载之后,将页面中有价值的信息初步提取和解析出来,再转发给后续的信息解析和存储等服务。
常见的数据预处理可能会包含:
- url/页面信息分析,用以确定该url/页面是否有抓取价值
- 页面信息下载,将页面里的数据下载下来进行分析
- 目标内容提取,从整个页面的标签组里把目标内容解析出来,构建成结构化的数据传给下游系统。
- 页面信息上报,用来记录自己的运行记录,方便后续的工作控制、页面去重等需要
数据清洗和解析
后端服务收到爬虫抓取的结构化数据之后,会进行数据进一步的清洗和解析,主要包含数据的转码、解码,不合理信息剔除、有效信息提取、内容分析打标签等。
数据存储
结构化数据在经过了解析之后,会通过相关服务转发给不同的存储系统进行保存,保存的信息主要包含数据源、url、标题正文、发布时间、多媒体地址、标签等内容。
同时,为了保证数据存取的效率,也会针对数据的时间、种类等属性进行规划,最后存入不同的存储集群和解决方案。
数据索引
在数据存储时,为了能对数据进行快速的搜索,系统会尝试对数据进行索引。索引中与数据抓取关系较大的主要是对数据/信息去重的部分,主要体现为对原地址、页面内容等的编码,以及对资源metadata的建模。
其余的,资源、内容等的部分的索引和数据抓取的联系不大,本文不做展开阐述。