目录
爬虫与反爬虫之间的战争
第一天
小莫想要某站上所有的电影,写了标准的爬虫(基于 httpClient 库),不断地遍历某站的 电影列表页面,根据 Html 分析电影名字存进自己的数据库。
这 个 站 点 的 运 维 小 黎 发 现 某 个 时 间 段 请 求 量 陡 增, 分 析 日 志 发 现 都 是 IP(xxx.xxx.xxx.xxx)这个用户,并且 user-agent 还是 Python-urllib/2.7 ,基于这两点判断非人类后直接在服务器上封杀。
第二天
小莫电影只爬了一半,于是也针对性的变换了下策略:
1. user-agent 模仿百度 (“Baiduspider…”),
2. IP 每爬半个小时就换一个 IP 代理。
小黎也发现了对应的变化,于是在服务器上设置了一个频率限制,每分钟超过 120 次请 求的再屏蔽 IP。 同时考虑到百度家的爬虫有可能会被误伤,想想市场部门每月几十万的投 放,于是写了个脚本,通过 hostname 检查下这个 ip 是不是真的百度家的,对这些 ip 设 置一个白名单。
第三天
小莫发现了新的限制后,想着我也不急着要这些数据,留给服务器慢慢爬吧,于是修改了代码,
随机 1-3 秒爬一次,
爬 10 次休息 10 秒,
每天只在 8-12,18-20 点爬,
隔几天还休 息一下。
小黎看着新的日志头都大了,再设定规则不小心会误伤真实用户,于是准备换了一个思 路,当 3 个小时的总请求超过 50 次的时候弹出一个验证码弹框,没有准确正确输入的话就 把 IP 记录进黑名单。
第四天
小莫看到验证码有些傻脸了,不过也不是没有办法,先去学习了图像识别(关键词 PIL, tesseract),再对验证码进行了二值化,分词,模式训练之后,总之最后识别了小黎的验证码 (关于验证码,验证码的识别,验证码的反识别也是一个恢弘壮丽的斗争史…),之后爬虫又 跑了起来。
小黎是个不折不挠的好同学,看到验证码被攻破后,和开发同学商量了变化下开发模式, 数据并不再直接渲染,而是由前端同学(js)异步获取,并且通过== JavaScript 的加密库生成 动态的 token==,同时加密库再进行混淆(比较重要的步骤的确有网站这样做,参见淘宝和微博 的登陆流程)。
第五天
混淆过的加密库就没有办法了么?当然不是,可以慢慢调试,找到加密原理,不过小莫 不准备用这么耗时耗力的方法,他放弃了基于 httpClient 的爬虫,选择了内置浏览器引擎的 爬虫(关键词:PhantomJS,Selenium),在浏览器引擎运行页面,直接获取了正确的结果,又 一次拿到了对方的数据。
小黎:…
爬虫与反爬虫的斗争还在继续… 通常情况下,在爬虫与反爬虫的对弈中,爬虫一定会胜利。
换言之,只要人类能够正常访问的网页,爬虫在具备同等资源的情况下就一定可以抓取
到。
一、反爬虫常见方法
1. IP 限制
IP 限制是很常见的一种反爬虫的方式。服务端在一定时间内统计 IP 地址的访问 次数,当次数、频率达到一定阈值时返回错误码或者拒绝服务。
2. 验证码
验证码是一种非常常见的反爬虫方式。服务提供方在 IP 地址访问次数达到一定 数量后,可以返回验证码让用户进行验证。
这种限制在不需要登录的网页界面比较 常见,它需要结合用户的 cookie 或者生成一个特殊标识对用户进行唯一性判断,以 防止同一个 IP 地址访问频率过高。
验证码的存在形式非常多,有简单的数字验证码、 字母数字验证码、字符图形验证码,网站也可以用极验验证码等基于用户行为的验 证码。
遇到这种情况,必须要搞清楚标识的生成方式,进 而模拟真实用户的访问。
3. 登录限制
登录限制是一种更加有效的保护数据的方式。网站或者 APP 可以展示一些基础的数据,当需要访问比较重要或者更多的数据时则要求用户必须登录。
例如,在天 眼查网站中,如果想要查看更多的信息,则必须用账号登录;
“知乎”则是必须在登 录后才能看到更多的信息。
登录后,结合用户的唯一标识,可以进行计数,当访问 频度、数量达到一定阈值后即可判断为爬虫行为,从而进行拦截。
针对“登录限制” 的方法,可以使用大量的账号进行登录,但成本通常比较高。
4. 数据伪装
在网页上,我们可以监听流量,然后模拟用户的正常请求。
在这种情况下,某些网站会 对数据进行一些伪装来增加复杂度。
该网站使用特殊的字体对数据进行了伪装。例如,3400,对应显示的是 1400, 如图 1-2 所示。如果能够找到所有的字体对应的关系,则可以逆向出正确的价格。
二、反反爬虫常见方法
1. 代理设置
(1)高匿名代理
高匿名代理会将数据包原封不动地转发,从服务端来看,就像是真的一个普通客户端在访问,而记录的 IP 地址是代理服务器的 IP 地址,可以对很好地隐藏访问源, 所以这种代理为爬虫工具首选。
(2)普通匿名代理
普通匿名代理会在数据包上做一些改动,代理服务器通常会加入的 HTTP 头有 HTTP_VIA 和 HTTP_X_FORWARDED_FOR 两种。根据这些 HTTP 头,服务端可以发现这是一个代理服务器,并且可以追踪到客户端的真实 IP 地址。
(3)透明代理
透明代理不仅改动了数据包,还会告诉服务器客户端的真实 IP 地址,因此在抓 取数据时应该避免使用这种代理服务器。
网上有一些免费代理列表网站会定期扫描互联网,从而获取一些代理服务器的信息,然后将这些信息公布出来。这些代理服务器的有效期可能比较短,也容易被滥用,质量通常较差,所以需要客户端自己筛选出可用的代理。
在代理的种类上,HTTP 代理多,HTTPS 代理较少。在互联网倡导 HTTPS 的 趋势下,单纯使用 HTTP 代理是无法访问 HTTPS 网址的。大部分往往网站会同时保留 HTTPS 和 HTTP 的访问,所以可以试着将 HTTPS 网址改为 HTTP(协议),一个 原则是,如果网站的 HTTP 可以用,则不要使用 HTTPS。原因是 HTTPS 需要多次握 手,速度比较慢,经过代理之后会显得更慢。HTTP 则会快很多,而且代理服务器可选资源较多,HTTP 代理列表如图 1-5 所示,HTTPS 代理列表如图 所示。
2. 构建代理池
网络上存在着大量的代理列表可以免费获取,虽然有效性通常少于 10%,但基
于庞大的数量(通常每日可获得上万个),也会有近千个代理可以用。在 GitHub 上 有很多抓取这类代理的项目,但质量良莠不齐,很难满足需要。经过对比后,我选 择了 ProxyBroker 这个项目。
ProxyBroker 是一个开源项目,可以从多个源异步查找公共代理并同时检查它们 的有效性。它比较小巧,代码不复杂且易于扩展,不依赖于 Redis 等第三方依赖,非 常专注地做好了抓取代理这件事。
特点:
从大约 50 个来源中找到 7000 多个代理工作。
支持协议:HTTP/HTTPS,Socks4/5;还支持 CONNECT 方法的 80 端口和 23 端口(SMTP)。
代理可以按照匿名级别、响应时间、国家和 DNSBL 中的状态进行过滤。
支持充当代理服务器,将传入的请求分发到外部代理,使用自动代理轮换。
检查所有代理是否支持 cookie 和 Referer(如需要,还检查 POST 请求)。 自动删除重复的代理。 异步获取。ProxyBroker 支持命令行操作,可以作为一个单独的工具使用。
3. 设置请求频率
修改了代码,
随机 1-3 秒爬一次,
爬 10 次休息 10 秒,
每天只在 8-12,18-20 点爬,
隔几天还休 息一下。