最近运维工作中单位的网站被攻击,我们的反爬虫系统已经比较严格了,突然有5个用户登录30多万次经我们查找发现,用户是正常登录,这一异常被我们的技术部门捕捉到第一时间响应,没想到常规架构已经不足以应付现在的技术了,对反爬虫做一个总结。
文章目录
- 一、事件起由
- 二、爬虫类型
- 1、身份伪装
- 2、降低主IP访问频率
- 三、编写基础爬虫原理
- 1、分析页面请求格式
- 2、构建合适的HTTP请求
- 3、批量发送HTTP请求并获取数据
- 四、编写高级爬虫原理
- 1、分布式爬虫
- 2、模拟JavaScript
- 3、使用PhantomJS
- 五、不同级别爬虫的优缺点分析
- 六、反爬虫系统设计的常规架构
- 1、对访问量进行统计,并封锁超过阈值的单个IP地址
- 2、对访问量进行统计,并封锁超过阈值的单个会话(session)
- 3、对访问量进行统计,并封锁超过阈值的单个用户代理(userAgent)
- 4、组合使用
- 七、总结
一、事件起由
门户网站的登录页面突然加载时间变成原来的4到5倍,部门快速响应,排查原因,没有被异常攻击,后来发现5个正常登录的用户登录次数过于频繁,明显不是人类能达到的手速,而我们的网站还有图片验证,这是有意而为的爬虫行为,所以我们部门快速响应,指定方案。
二、爬虫类型
1、身份伪装
自定义Headers请求
request = urllib.request.Request(url,headers=head)
- user-agent修改:修改存储的系统和浏览器的型号版本信息
- referer修改:不直接发起请求,修改检查请求的来源URL
- cookie修改:观察需爬虫网站的Cookie格式,并进行伪造
headers = {'Referer':'https://accounts.pixiv.net/loginlang=zh&source=pc&view_type=page&ref=wwwtop_accounts_index',#如某些网站(如p站)要检查referer,就给他加上'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'#每个爬虫必备的伪装}
r = requests.get("https://segmentfault.com/a/1190000014383966",headers=headers)
2、降低主IP访问频率
- 休眠:降低访问频率和次数
- ip代理:使用环境变量 http_proxy 来设置 HTTP Proxy
proxies={ 'http': 'http://xx.xx.xx.xx:xx' }
time.sleep(60)#用python自带time模块的休眠功能
proxies = {'http': 'http://10.10.1.10:3128',#“协议类型:完整ip地址+端号”'https': 'http://10.10.1.10:1080'}#代理ip字典,随机调用
r = requests.get(url,headers=headers,proxies=proxies)
三、编写基础爬虫原理
在进行反爬虫工作之前,首先需要掌握如何编写基础的爬虫程序。
目前,网络上关于爬虫的资料相对有限,通常仅提供一段Python代码示例。尽管Python是一门强大的编程语言,但针对已实施反爬虫措施的网站,Python并非最佳选择。
讽刺的是,许多公开的Python爬虫代码通常会使用一个名为lynx的用户代理(User-Agent)。至于如何处理这个User-Agent,这里无需多言。
编写爬虫程序通常需要经过以下几个步骤:
1、分析页面请求格式
理解目标页面的请求结构和数据传输方式。
2、构建合适的HTTP请求
根据页面分析结果,创建与目标网站交互的HTTP请求。
3、批量发送HTTP请求并获取数据
通过循环发送HTTP请求,批量获取所需数据。
例如,当你访问一个在线购物网站时,你可能会在产品详情页点击“加入购物车”按钮,这会触发页面加载并更新购物车中的商品数量和总价。如果你的目标是获取购物车中的产品信息,你需要确定哪个网络请求包含这些数据。
一个有效的做法是通过浏览器的开发者工具查看网络请求。在分析这些请求时,你可以通过数据传输量来筛选和排序。通常,包含重要数据的请求会传输较大的数据量,而其他请求则相对较小。通过这种方法,你可以快速找到与购物车信息相关的请求,从中提取所需的数据。只需根据网络传输的数据量对请求进行倒序排列。尽管页面可能生成多个复杂的URL,开发人员通常不会将大量数据附加在无关的请求上
四、编写高级爬虫原理
编写高级爬虫进阶技巧包括以下几种:
1、分布式爬虫
一些教程建议将爬虫分布式部署在多台机器上,以提高抓取效率。然而,这种说法并不完全正确。分布式爬虫的主要目的是规避目标网站对单个IP的封禁。封IP是反爬虫的终极手段,虽然非常有效,但也可能误伤正常用户。
2、模拟JavaScript
有些教程将模拟JavaScript和抓取动态网页视为进阶技巧,但实际上,这只是一个基础功能。如果目标网站没有实施反爬虫措施,你可以直接抓取Ajax请求的数据,无需过多关注JavaScript的处理过程。但如果对方采取了反爬虫措施,JavaScript的逻辑往往会变得复杂,此时关键在于深入分析,而不仅仅是简单的模拟。因此,掌握JavaScript模拟应当视为基本功。
3、使用PhantomJS
PhantomJS是一个极端的例子。它原本是用于自动化测试的工具,但由于其强大的功能,许多人将其用于爬虫。然而,PhantomJS有一个明显的缺点:效率低。此外,PhantomJS本身也容易被检测到,尽管涉及的技术细节较为复杂,这里不再详述。
五、不同级别爬虫的优缺点分析
较低级的爬虫虽然容易被封锁,但其性能优越,成本较低。而越是高级的爬虫,虽然难以被封锁,但其性能较低,成本也显著增加。
爬虫级别 | 性能 | 成本 |
---|---|---|
低级 | 高 | 低 |
高级 | 低 | 高 |
当反爬虫的成本高到一定程度时,继续封锁爬虫就可能变得不再必要。在经济学中,这种现象被称为边际效应,即当成本增加到某个临界点时,额外的收益将逐渐减少。
因此,在对比双方资源时,我们可以发现,执意与对方在反爬虫技术上较量并不划算。应当找到一个最佳平衡点,超过这一点时,不妨允许其继续爬取数据。毕竟,反爬虫的目标是基于商业利益,而非为了显示技术能力。
六、反爬虫系统设计的常规架构
1、对访问量进行统计,并封锁超过阈值的单个IP地址
这种方法虽然有效,但存在两个明显缺陷。首先,它容易误伤普通用户;其次,IP资源成本低廉,可以轻易购买大量IP地址。因此,从总体上看,这种策略的性价比不高。然而,对于初级爬虫,仍然有一定的效果。
2、对访问量进行统计,并封锁超过阈值的单个会话(session)
虽然看起来更高级一些,但效果实际上更差。因为session同样不具备成本,可以轻松重新生成。因此,这种方法的有效性有限。
3、对访问量进行统计,并封锁超过阈值的单个用户代理(userAgent)
这是一个强有力的策略,类似于使用抗生素,效果显著,但副作用也大。误伤普通用户的风险很高,使用时需格外谨慎。我们至今只在极少数情况下短暂封锁过特定平台下的浏览器。
4、组合使用
将这些措施结合起来使用,可以提升整体的防护能力,同时降低误伤率。在应对低级爬虫时,这种组合策略相对有效。
由此可见,反爬虫与爬虫之间实际上是一场博弈。最终的赢家往往是那些有资源投入的“玩家”。由于上述方法效果各有优劣,因此,使用JavaScript进行防护通常更为可靠。
七、总结
我们的网站使用的是随机校验码,由于我们是3级防护等级,12306是4级,成本达不到。所以按照现有的最优解决方案,我们升级了我们的随机校验码,暂时阻止了此次攻击,未来如果还有类似的攻击,我们准备加入手机短信的验证,进一步遏制恶意登录操作。这次事件为我们的网络安全防护带来了重要启示,并成为我们反爬虫技术的核心理念之一:及时变更。
参考文献:
[1]携程技术中心. 关于反爬虫,看这一篇就够了[R/OL][2016-06-30].https://segmentfault.com/a/1190000005840672
[2]忍野忍.Python 从零开始爬虫(零)——爬虫思路&requests模块使用[R/OL][2018-04-14].https://segmentfault.com/a/1190000014383966
[3]忍野忍.Python 从零开始爬虫(一)——爬虫伪装&反“反爬”[R/OL][2018-04-14].https://segmentfault.com/a/1190000014431323