首页 > 技术文章 > 常见的反爬机制说明和相应的解决方法

niansi 2017-02-13 00:14 原文

1. Headers

从用户的headers进行反爬是最常见的反爬虫策略。Headers是一种区分浏览器行为和机器行为的最简单的方法,还有一些网站会对 Referer (上级链接)进行检测(机器行为不太可能通过链接跳转实现)从而实现反爬虫。

相应的解决措施:通过审查元素或者开发者工具获取相应的headers 然后把相应的headers传输给python的requests(请求头),这样就能很好地绕过。

备注:Headers 相关知识:

host:提供了主机名及端口号

Referer 提供给服务器客户端是从哪个页面链接过来的信息(有些网站会据此来反爬)

Origin:Origin字段里只包含是谁发起的请求,并没有其他信息。跟Referer不一样的是Origin字段并没有包含涉及到用户隐私的URL路径和请求内容,这个尤其重要。

并且Origin字段只存在于POST请求,而Referer则存在于所有类型的请求。

User agent: 发送请求的应用程序名(一些网站会根据UA访问的频率来进行反爬)

proxies: 代理,一些网站会根据ip访问的频率次数等选择封ip

cookie: 特定的标记信息,一般可以直接复制,对于一些变化的可以选择构造(python中的一些库也可以实现)

Accept首部为客户端提供了一种将其喜好和能力告知服务器的方式,包括他们想要什么,
可以使用什么,以及最重要的,他们不想要什么。这样服务器就可以根据这些额外信息,对要发送的内容做出更明智的选择。

首部            描述

Accept          告诉服务器能够发送哪些媒体类型

Accept-Charset     告诉服务器能够发送哪些字符集

Accept-Encoding     告诉服务器能够发送哪些编码方式(最常见的是utf-8)

Accept-Language    告诉服务器能够发送哪些语言

Cache-control: 这个字段用于指定所有缓存机制在整个请求/响应链中必须服从的指令

Public 所有内容都将被缓存(客户端和代理服务器都可缓存)

Private 内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存)

public max-age=xxx (xxx is numeric) 缓存的内容将在 xxx 秒后失效, 这个选项只在HTTP 1.1可用

No-store 不缓存

2. IP 限制

一些网站会根据你的IP地址访问的频率来进行反爬。也就是说,如果你用单一的 IP 地址访问频率过高,那么服务器会在短时间内禁止这个 IP访问。

解决措施:构造自己的 IP 代理池,然后每次访问时随机选择代理(但一些 IP 地址不是非常稳定,需要经常检查更新)

3. UA限制

UA是用户访问网站时的浏览器标识,其反爬机制与ip限制类似。

解决措施:构造自己的UA池,每次python做requests访问时随机挂上UA标识,更好地模拟浏览器行为。当然如果反爬对时间还有限制的话,可以在requests 设置timeout(最好是随机休眠,这样会更安全稳定,time.sleep())

附:常见的浏览器标识:

User-Agent: Mozilla/5.0 (Macintosh; U; IntelMac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1Safari/534.50

'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)

4.验证码反爬虫或者模拟登陆

验证码:这个办法的反爬效果非常好,如果一个爬虫要解释一个验证码中的内容,这在以前通过简单的图像识别是可以完成的,但是就现在来讲,验证码的干扰线,噪点都很多,甚至还出现了人类都难以认识的验证码(比如说12306)。

嗯,如果一个爬虫要访问的页面提示要输入验证码,那么问题就来了,不是所有的爬虫都装备了图像识别技术啊。其实大家要问了,爬虫处理这些登录页面有什么意义呢?除非你是想爆破密码或者是刷xxx什么的。但是真的有人把验证码用在反爬虫上的么?事实上确实有,Google就在使用,如果有使用google经验的读者会发现自己在愉快查google,特别是使用vpn或者是各种科学上网工具的时候,经常会提示你google想知道你是不是一个人(不是人还能是什么?)
相应的解决措施:验证码识别的基本方法:截图,二值化、中值滤波去噪、分割、紧缩重排(让高矮统一)、字库特征匹配识别。(python的PIL库或者其他)

模拟登陆(例如知乎等):用好python requests中的session(下面几行代码实现了最简单的163邮箱的登陆,其实原理是类似的~~)

import requests
s =requests.session()
login_data={"account":" ","password":" "}
res=s.post("http://mail.163.com/",login_data)

5.Ajax动态加载

网页将不希望被爬虫获取的数据使用Ajax动态加载,这样就为爬虫造成了绝大的麻烦。如果一个爬虫不具备js引擎,或者具备js引擎,但是没有处理js返回的方案,或者是具备了js引擎,但是没办法让站点显示启用脚本设置。基于这些情况,ajax动态加载反制爬虫还是相当有效的。

Ajax动态加载的工作原理是:从网页的 url 加载网页的源代码之后,会在浏览器里执行JavaScript程序。这些程序会加载出更多的内容,并把这些内容传输到网页中。这就是为什么有些网页直接爬它的URL时却没有数据的原因。

处理方法:若使用审查元素分析”请求“对应的链接(方法:右键→审查元素→Network→清空,点击”加载更多“,出现对应的GET链接寻找Type为text/html的,点击,查看get参数或者复制Request URL),循环过程。如果“请求”之前有页面,依据上一步的网址进行分析推导第1页。以此类推,抓取抓Ajax地址的数据。对返回的json使用requests中的json进行解析。

6.cookie限制

网页在打开时会随机生成一个cookie,如果再次打开网页时这个cookie不存在,第三次打开仍然不存在,这就非常有可能是爬虫在工作了。

解决措施:在headers挂上相应的cookie或者根据其方法进行构造(例如从中选取几个字母进行构造)。如果过于复杂,可以考虑使用selenium模块(可以完全模拟浏览器行为)

推荐阅读