龙空技术网

知物由学 | 人工智能时代,如何反爬虫?

网易易盾 145

前言:

目前你们对“反爬虫nginx”大致比较珍视,同学们都想要了解一些“反爬虫nginx”的相关知识。那么小编在网上汇集了一些有关“反爬虫nginx””的相关文章,希望小伙伴们能喜欢,大家一起来学习一下吧!

​​“知物由学”是网易易盾打造的一个品牌栏目,词语出自汉·王充《论衡·实知》。人,能力有高下之分,学习才知道事物的道理,而后才有智慧,不去求问就不会知道。“知物由学”希望通过一篇篇技术干货、趋势解读、人物思考和沉淀给你带来收获的同时,也希望打开你的眼界,成就不一样的你。当然,如果你有不错的认知或分享,也欢迎在“网易易盾”公众号后台投稿。


随着互联网开放式、爆发式地增长,数据的价值变得越来越重要,尤其是电商、传媒、社交等等业务,将数据比作黄金也不为过。因而随之诞生了网络爬虫技术,黑客通过调用网站开放的免费接口来批量获取有价值的数据,用以数据挖掘和分析行业状况等。然而大量的非法爬虫会造成网站服务器压力巨大,甚至影响正常用户的访问;而且有价值的数据被窃取,也会对网站的商业利益造成负面影响。


因此反爬虫技术应运而生。反爬虫技术大体包含“爬虫识别”和“爬虫反制”两个步骤,后者主要是用于对前者识别出的爬虫出的爬虫进行惩罚和反制,主要包括限制访问、验证码校验、数据投毒等等,本文不做深究。而前者目前常用的方式是基于规则判断。比如以某个用户或者IP为单位,统计其在一定时间内的访问记录,然后用人为设定的一些阈值,这种可以称为专家规则方法。其优点是规则明确、可靠,可以实时针对发现的爬虫特征来设定规则,从而实现与爬虫对抗。


但是它也有明显的缺点:

强依赖运营的经验,规则和阈值难以凭空设定;
与爬虫对抗依赖人为观察爬虫的特征;
当规则越来越复杂且数量庞大时,规则引擎的效率会越来越低,成本会比较大。

由于上述原因,我们结合了两项热门的技术:大数据和机器学习,来探究其在爬虫识别中的应用。


一、基于Flink的大数据统计


首先我们需要通过一些大数据技术来获取统计数据。Flink是一个新兴的分布式大数据流处理引擎,本文不做详细介绍,只是利用了其基于事件时间窗口统计数据的功能。
流处理过程主要包含以下步骤:


Flink流处理过程

数据源:我们的数据源是业务网站吐出的Nginx访问日志,保存在kafka队列中。预处理:按照数据源中的数据格式,将访问日志中有用的字段解析出来,主要是Timestamp、IP、URI、Htpp_User_Agent等。维度聚合:利用Flink的keyby功能,将同一IP的数据汇总起来。时间窗口:利用Flink的Window功能,把Timestamp处于某一时间窗口内的数据汇总到一起。我们采用的是滑动窗口的方式,统计15分钟之内的数据,每1分钟滑动一次。统计:通过以上两步,我们每1分钟结束,都能获得每个IP在前15分钟内的所有访问记录。我们对这些数据进行进一步统计,得到的数据以Json形式写入到Kafka,格式如下图


Flink输出数据

字段含义:

Timestamp:窗口结束时间的时间戳;IP:该数据所属的IP;Sum:该IP在时间区间内的总访问次数URI:该IP在时间区间内访问的URI的具体统计

a)counts: 是一个map,key是所访问的URI,value是访问计数

b)count: counts中不同key的数量

c)sum: counts中所有value的和

d)min: counts中所有value的最小值

e)max: counts中所有value的最大值

Http_User_Agent:该IP在时间区间内访问记录所使用的User Agent的具体统计。内部的counts、count、sum、min、max与URI中的类似其他还有一些字段如http_referer、status、params、http_version等也类似,不再一一列出。


二、数据的特征提取


要利用机器学习的算法来实现爬虫的判断,首先要将原始数据转化为向量,向量中的维度数据要尽量包含数据的特征,这样才能尽可能地区分爬虫和正常记录的差异。


通过观察发现,爬虫记录与正常记录相比,主要有以下特征:

访问总计数sum偏高;每个URI的访问计数较高;访问的URI比较集中,通常只访问特定的几个URI,而且可能呈现一定的比例;访问所用的User Agent比较单一;每个User Agent的计数都很接近;


针对以上特征,我们用以下维度来组成数据的特征向量:

普通维度:这些维度是直接采用原始数据中的统计量,比如sum、URI.count、URI.max、URI.min、http_user_agent.count、http_user_agent.max、http_user_agent.min等等方差维度:考虑到URI、http_user_agent等字段的不同取值的分布情况也是重要的特征,把counts中value的方差也作为特征维度订制维度:业务方对其URI分布有一定的了解,可以对URI.counts中的数据做一个二次统计,产生一些订制维度。比如把key匹配正则表达式“^/api/v\\d+/products/.*”的记录的value相加,来作为一个新的特征维度。同样的也可用http_user_agent.counts中的数据产生订制维度


三、线下分析


我们采用神经网络算法,该算法的优点是: 技术成熟、适应性强、工程化容易、可移植性强等等。但是它是一种有监督学习,需要有一批训练数据才能工作。


3.1 训练数据获取阶段:


获取训练数据的思路有两种:

3.1.1 借助规则引擎法:我们已经拥有一个规则引擎,可以用它配置一些简单的规则,然后把规则引擎判断出的结果作为标记,和原始数据一起作为训练集数据。这种方法的优点是简单、直观;且规则越复杂,则相应训练出来的模型也越优秀,区分爬虫的能力越强。但是缺点也是很明显的,因为依赖了规则引擎,所以也继承了规则引擎的弊端,要创建合适的规则比较困难,而且学习后的模型也只是能起到和规则引擎一样的效果,无法识别更多特殊的异常。所以该方法必须要搭配数据反馈和模型进化,才能使模型更加智能。


3.1.2 人工标记法:这也是一种常见的获取训练集的方式,训练集越完备,数据代表性越好则训练出来的模型越优秀。但是该种方法最大的缺点是工作量巨大,面对海量的大数据,我们不可能做到一一标记,因此这种方法的难点就在于如何高效地获取有效数据。


我们采用的方法是基于PCA+Kmeans的无监督学习算法,大概步骤如下:

先采样一批提取完特征的数据作为输入对原始的特征数据做PCA主成分分析,通过线性变换获得方差最大的几个主成分维度,作为新的、降维后的特征向量,这一步是为了提取特征向量中的有效成分,去除无用信息对降维后的数据采用Kmeans算法进行聚类,得到若干个类别,并且对每条数据标记类别号对于每类数据,抽取最有代表性的若干条数据,人为分析对应的原始数据,判断是否为爬虫,然后计算抽取数据中爬虫的比例。如果比例超过一定阈值,则将该类标记为爬虫;如果比例小于一定阈值,则将该类标记为正常;比例在上下阈值之间的做对类内数据做进一步聚类,再做类似的判断用类别的标记来标记类内的每条数据,得到了带标记的训练数据集这种方式需要在效果和工作量之间做取舍。当然也可以搭配数据反馈和模型进化,使模型表现更好。


3.2 模型构建和训练阶段


使用Pytorch搭建神经网络模型。可以分批、多组地用同一批数据反复训练模型。 当达到一定的迭代次数,或者损失函数小于一定阈值,则表示模型训练完毕。可以将模型参数文件导出,供线上部署。


一个简单的单层神经网络例子

训练过程

在测试集上的测试结果


四、线上部署


模型引擎的线上部署如下图所示。Training模块负责数据的线下处理和训练,训练完的模型文件上传至Nos,然后将模型的配置信息以及模型文件的地址写入Etcd。Model Engine模块是线上的模型引擎,实时监听Etcd中额配置,当配置更新时,会立即拉取模型文件,并加载。


Model Engine会消费Flink统计完写入Kafka的数据,并用模型做爬虫判别,并将判别的结果写入数据库,供其他系统查询使用。


线上部署架构


五、模型进化


到此我们已经搭建了包含数据采集、线下训练、线上部署的模型引擎架构,但是正如前面所说,目前的模型只能达到与规则引擎相近的效果,要想让模型进化得更为智能,必须加入反馈机制,使得模型能够进化。


反馈的思路是从模型引擎的输出数据入手。神经网络分类算法的输出数据,除了包含记录是否属于爬虫的判断,还包含是否属于爬虫的概率。可以根据概率分为三段:非爬虫:0~33%、疑似爬虫:33%~66%,爬虫:66%~100%。


对三段抽样进行人工分析:

非爬虫、爬虫段:抽取少量数据,检查是否有误杀和漏杀;嫌疑段:抽取大量数据来重点分析,判断是否为爬虫;


将分析完的数据作为新的训练集,对原来训练好的模型进行增量训练,使模型在保留部分历史经验的情况下获取新的特性。这一步当然也可以结合一些别的增量学习、迁移学习以及强化学习的算法来实现。


标签: #反爬虫nginx