反爬小述

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了反爬小述相关的知识,希望对你有一定的参考价值。

参考技术A title: 反爬小述

tags:

categories:

comments: true
date: 2018-04-01 14:00:00

反爬虫是一个持续、对抗的过程,没有一劳永逸的方法,需要不断的投入,所以,无法完全的防治爬虫,而反爬虫要做的其实归纳起来很简单:不断提升爬虫爬取成本。

很多网站的对于核心数据在前端展示时都做了一些数据隐藏、编码等手段(比如图片替换文字、字符映射),对于爬虫而言,即使拿到 html,但是解析其中的内容也比较复杂。部分网站还采用动态 url生成的防范机制,难度更高。

前端做保护工作在一定程度上能提高对核心数据的保护,不断的更新前端保护机制,爬虫也需要不断研究破解机制,对爬虫来说是非常耗时的操作。

猫眼电影的一些数值类数据,包括票房、票价等都是通过 “stonefont” 控制,并不是真正的数字,需要通过对应的字体字符集映射回去,而且每次请求下发的映射都是动态的:

所以爬取时需要兼顾爬取 html 以及字符映射关系,然后自行解析。

去哪儿票价通过前段 html 多个元素叠加合成,要是稍不注意,爬取的就是脏数据:

以 web 端访问为例,正常的浏览器请求包含有效的 UA,cookie,referer 等常规信息,爬虫要完全兼顾此类信息成本较高。同样的,此类方法由于不同的浏览器特质(比如微信内浏览器)也相对容易出现误伤。

设备指纹在安全风控反作弊领域常用手段之一,通过采集设备、浏览器的信息来唯一的标识设备,通过此属性能很大程度的标识是否是无头浏览器、模拟器以及直接通过后端接口爬取数据。

通过 header 的检测方法实时性更强,其无需大量的数据积累,在兼顾准确性与误伤的同时,能更快的识别爬虫,而代价为了控制误伤就是遗漏率略高。

访问频次是爬虫检测最基本的手段之一,正常用户的在浏览内容时,在单位时间内(比如1min,10 min,1hour)访问某个 path 的数值不会超过过某一阈值,这一阈值和访问具体 path 也相关,比如 zl 内容一般较多,所以阈值相对较低,而 comment 则相对较高。但是爬虫、尤其是初级爬虫,毕竟是机器访问很容易突破这一阈值,被反爬系统限制。

访问频次的检测手段对于不同的维度 member、ip、device 要有不同的阈值,尤其是 ip 维度,因为存在 “网关 ip” 这种特例,阈值相对 member 要高一些,但这样仍会会存在爬虫混在正常用户的群体中的 demo,比如校园出口 ip,学生是初级爬虫的主要生产者之一,所以 ip 访问频次的阈值虽然要相对 member、device 要大一些,但仍不能过被爬虫钻空子。

这种情况下,在限制爬虫时可以区分对待,当限制主体为 ip 时,对于已经登录的用户不会产生影响,但未登录用户会被限制,而登录用户则在以 member、device 为识别限制主体。

通过频次识别爬虫在应对初级爬虫或首次爬虫时效果较明显,能起到一定的保护后端服务以及数据的效果,但当爬虫通过调试后,能够逐渐摸索出我们的访问阈值从而控制自身的访问频率,避免被识别。此时,爬虫通分布式多 ip 策略仍能够大量、快速的爬取数据。

对于此类情况,基于行为特征的识别能发挥更大的作用。

对于爬虫而言,其行为相较正常访问用户,易出现以下特点:

通过此类特征能搞很好检测出因为访问频率低而被频率策略遗漏的爬虫。比如对于爬取用户信息的爬虫,其访问特征很明显,不同于正常用户基于内容的访问,其大部分访问集中在用户类的 url 上,所以在其整体访问较集中、访问 url 的离散度过低,通过这一特点很容易可以识别出此类爬虫。

对于暴露后端接口的服务,很多爬虫通过直接拉取后端接口的方式既可获得结构化的数据,这种网站简直是爬虫的最爱,省去的解析 html 的过程。当然这类爬虫也相对比较好防治,相对正常的浏览器访问,这类防虫不会访问一些浏览器必定会触发的 ajax 请求,所以通过对比两类数据可以相对比较容易识别。

对于抓取内容的爬虫,其和正常用户最大的不同在于,用户会受内容质量、个人兴趣习惯等多种因素的影响,导致其对于不同内容的停留时间不同,请求之间的访问间隔不一,单位时间内访问量不规律,而爬虫在这一点上模仿难度较高,普通一些的爬虫在这些特征的表现比较明显,通过制定简单的策略规则既可以识别,高级一些的爬虫会使用随机访问等掩护手段,在这时普通的规则效果较差,可以通过算法模型比如 SVM、HMM 等模型分析。

对于爬虫而言,更换 ip 是非常普及的一个手段,通过代理 ip 爬取更是爬虫的通用手段,很多代理 ip 网站都提供免费的代理 ip,github 上也有很多实时爬取这些代理网站 ip 并验证可用的资源,获取成本极低。对于反爬而言,收集这类资源同样有必要,和上述特征结合使用,能极大的提高准确率,当然有条件的可以购买一些第三方的数据情报。

除了代理 Ip 外,爬虫另外一个通用的手段就是动态拨号,对于这类ip ,需要注意控制误伤,避免长期封禁对正常用户的影响:

其他更换 ip 的手段还包括 “tor 洋葱网络(已被墙,延时较高)”,相对前两者使用人数较少。

比较通用的反爬拦截手段就是直接拦截掉用户的请求,返回 403 (或者其他状态码),切断爬虫的访问,但是这种情况比较适用于识别准确率较高的场景,对于疑似爬虫的请求一般采用验证码方式拦截。

验证码是各大厂拦截爬虫比较通用的手段之一,从最简单的字符验证码到 js 拖动验证码等等,通过算法也是一一被攻克:

除了算法破解,还有打码平台的存在,直接人工识别,更是大大降低了验证码的效果:

现在单纯的通过验证码已经能比较容易的被破解,google 的新式验证码效果极佳,对于误伤用户的体验也很好,他直接提供一个点击框,通过对比用户的行为特征、采集浏览器信息等(还有一些google 没有透漏的特征)能比普通验证码效果更好(据说区分人类和机器之间的微妙差异,在于他/她/它在单击之前移动鼠标的那一瞬间。),目前 stackoverflow 也使用了类似的验证码。所以在验证码页面采集多采集一些行为信息,设备信息等等可以作为进一步识别爬虫的依据。

投毒就是对于爬虫和正常人的返回不同的结果,给爬虫以假象,让其自己为爬取到了真实数据。这同样要求识别率较高,否则造成误伤对用户体验过差。

蜜罐也是安全圈中比较常见的一种手段,但是对于细心的爬虫来说,往往不易上当。

对于被准确识别出来的爬虫,其 ip、member 信息可以构建一套自己的黑名单库,积累这种资源类数据,毕竟代理 ip、失控帐号这类数据复用相对还是比较高的。

http://www.freebuf.com/articles/web/137763.html
http://bigsec.com/bigsec-news/anan-16825-Antireptile-zonghe
https://www.zhuyingda.com/blog/article.html?id=8
http://www.sohu.com/a/166364494_505779
http://www.cqvip.com/main/export.aspx?id=672889284&
https://github.com/equalitie/learn2ban
https://patents.google.com/patent/CN103631830A/zh
http://www.xueshu.com/jsjyxdh/201704/28789559.html
http://www.sohu.com/a/207384581_609376
https://www.zhuyingda.com/blog/b17.html

https://github.com/luyishisi/Anti-Anti-Spider/blob/master/7.IP%E6%9B%B4%E6%8D%A2%E6%8A%80%E6%9C%AF/README.md
https://github.com/SpiderClub/haipproxy

https://www.urlteam.org/2017/03/tensorflow%E8%AF%86%E5%88%AB%E5%AD%97%E6%AF%8D%E6%89%AD%E6%9B%B2%E5%B9%B2%E6%89%B0%E5%9E%8B%E9%AA%8C%E8%AF%81%E7%A0%81-%E5%BC%80%E6%94%BE%E6%BA%90%E7%A0%81%E4%B8%8E98%E6%A8%A1%E5%9E%8B/

http://imweb.io/topic/595b7161d6ca6b4f0ac71f05
https://www.urlteam.org/2016/11/%E5%9B%9B%E5%A4%A7%E8%A7%86%E9%A2%91%E7%BD%91%E7%AB%99%E5%8F%8D%E7%88%AC%E8%99%AB%E6%8A%80%E6%9C%AF%E7%A0%94%E7%A9%B6/

常见的反爬措施:UA反爬和Cookie反爬

本文分享自华为云社区《Python爬虫反爬,你应该从这篇博客开启,UA反爬,Cookie 特定参数反爬》,作者:梦想橡皮擦。

通过前面的爬虫程序,你或许已经注意到,对于目标站点来说,爬虫程序是机器访问,从目标站点的角度来看,爬虫带来的流量都是“垃圾流量”,是完全没有价值的(刷量类爬虫除外)。

为了屏蔽这些垃圾流量,或者为了降低自己服务器压力,避免被爬虫程序影响到正常人类的使用,开发者会研究各种各样的手段,去反爬虫。

爬虫与反爬虫是一对共生关系,有爬虫工程师,就必然存在反爬工程师,很多时候,爬虫工程师与反爬工程师都在斗智斗勇

反爬没有特定的分类,如果一个网站上了反爬代码,一般情况下会使用几种反爬措施搭配使用。

服务器验证请求信息类爬虫

本系列的博客从最简单的反爬手段开始学习,入门级反爬:“User-Agent” 用户代理反爬。

User-Agent

用户代理(User-Agent),表示的是用户的浏览器相关信息,该反爬逻辑是通过服务器端验证请求头中的 User-Agent 参数,然后区分是爬虫程序还是正常的浏览器访问。

访问任意网站,唤醒开发者工具,然后在控制台中输入 navigator.userAgent,就可以获取到 UA 字符串(User-Agent 字符串)。

UA 字符串的格式一般可以这么理解:

平台 引擎版本 浏览器版本信息

如果在详细分解,可以得到如下格式:

浏览器标识 (操作系统标识;加密等级;浏览器语言) 引擎版本 浏览器版本信息

这样你在看上图所示的内容,就比较容易理解其含义了。

Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36

在不同的浏览器测试,你会发现 UA 字符串都以 Mozilla 开头,这是由于历史上的浏览器大战,导致的遗留问题。

下面对比市面上主流的三款浏览器的 UA 字符串。

# 谷歌浏览器
Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
# 火狐浏览器
Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:94.0) Gecko/20100101 Firefox/94.0
# IE11 浏览器
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko

分析上述内容中的相关数据含义

  • Mozilla/5.0:表示浏览器;
  • Windows NT 6.1:操作系统,我这里得到的是 Windows 7 操作系统;
  • Win64/WOW64:64 位操作系统;
  • x64:发行版本;
  • N,I,U:加密等级,这里没有出现;
  • AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36:这个如果你去研究,也有很多趣事,不过咱们理解其是浏览器的版本就可以了。

有了基本的认知之后,我们就可以任意的去编写不同的浏览器标识了(多数时候是从开发者工具中直接复制)

相应的,服务器也能从这个字符串中,识别出访问它的浏览器相关信息(其实操作系统的信息也会被携带过去,甚至它可以验证该 UA 字段是否复合特定的规则)

案例实操环节

拿 CSDN 热榜进行测试,如果不设置 UA 字段,你将获取不到任何返回数据,你可以将下述 headers 置为空值,然后查看运行结果。

import requests

headers = 
    "user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"

res = requests.get('https://blog.csdn.net/phoenix/web/blog/hot-rank?page=0&pageSize=25', headers=headers)
print(res.text)

User-Agent 生成
可以使用 Python 第三方库,pip install fake_useragent,也可以自己维护一个 UA 类。
与 User-Agent 参数相同的还有 HOST 与 Referer,都可以认为的设置一些信息进行反爬。

Cookie 反爬虫

使用 Cookie 验证,也是常见的反爬,由于目标站点可遇不可求,所以接下来的内容从理论层面说明,在后续会结合复杂的案例进行实操。

Cookie 反爬虫最简单的手段
服务器端使用特殊的 Cookie 值进行验证,如果发现传递过去的 Cookie 值不存在,或者不符合生成规范,则不返回数据。

例如服务器验证固定 Cookie 字段,在前文获取热榜代码中,如果你不携带某些 Cookie 值,那得到的就不是完整的数据(可自行测试,差异值为 username)。

还有一种情况是验证 Cookie 是否符合某种格式,例如 Cookie 由 JS 动态生成,而且复合某种潜在(开发者约定)的规则,那该 Cookie 值传递到后台之后,后台工程师直接验证该值即可实现反爬效果,例如 Cookie 规则为 123abc123,前面 3 个随机数,后面 3 个随机数,中间三个随机小写字母,那后台工程师就可以通过正则验证客户端传递的 Cookie 值,是否复合规则,不符合,直接返回异常信息。

当然这种手段很容易被识别出来,进一步还可以加入时间戳,后台工程师拿到 Cookie 中的时间戳之后,验证当前时间的差值,如果超过了某个值,也可以认为该 Cookie 是伪造的。

Cookie 还被用于用户身份的验证,例如很多站点的数据只有登录之后才可以访问,原因是 Cookie 记录了用户信息,Cookie 的这个应用场景比较多,例如华为云博客的系统消息页面

系统消息_开发者-华为云

点击之后会跳转到登录页面,但如果你在请求头携带 Cookie 访问,则得到对应内容,其中最重要的一个 Cookie 字段是 HWS_ID,测试代码如下,你可以从开发者工具中复制出对应的 Cookie 字段访问该页面。

import requests
from lxml import etree

headers = 
    "user-agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36",
    "cookie": '你的HWS_ID Cookie值;'

res = requests.get('https://developer.huaweicloud.com/usercenter/mysysmessage', headers=headers, allow_redirects=False)
with open("./1.html", "w", encoding="utf-8") as f:
    f.write(res.text)
elements = etree.HTML(res.text)
print(elements.xpath("//title/text()"))

点击关注,第一时间了解华为云新鲜技术~​

以上是关于反爬小述的主要内容,如果未能解决你的问题,请参考以下文章

Python爬虫反爬,你应该从这篇博客开启,UA反爬,Cookie 特定参数反爬

Python反爬,JS反爬串讲,从MAOX眼X开始,本文优先解决反爬参数 signKey

爬虫进阶常见的反爬手段和解决方法(建议收藏)

字体反爬之快手

Python反爬,JS反爬串讲,从MAOX眼X开始,本文优先解决反爬参数 signKey

Python爬虫入门教程 64-100 反爬教科书级别的网站-汽车之家,字体反爬之二