反爬虫 笔记

对于一张网页,我们往往希望它是结构良好,内容清晰的,这样搜索引擎才能准确地认知它。
而反过来,又有一些情景,我们不希望内容能被轻易获取,比方说电商网站的交易额,教育网站的题目等。因为这些内容,往往是一个产品的生命线,必须做到有效地保护。这就是爬虫与反爬虫这一话题的由来。
但是世界上没有一个网站,能做到完美地反爬虫。
如果页面希望能在用户面前正常展示,同时又不给爬虫机会,就必须要做到识别真人与机器人。因此工程师们做了各种尝试,这些策略大多采用于后端,也是目前比较常规单有效的手段。

反爬手段

  1. User-Agent检测
  2. Referer检测
  3. IP限制频次
  4. 账号及Cookie验证
  5. 验证码
  6. 混淆或者加密js

各类型网站 爬虫难度

根据我爬取过的网站,爬虫难度从易到难依次是:

1. 新闻类网站

比如腾讯新闻、新浪新闻、网易新闻、和讯网、凤凰网等等
公开的信息,可以直接爬取。
很多都没有反爬策略,即使有,反爬策略也比较简单,User-Agent检测,IP限制频次,可能有一些有ajax网页,对新手来说可能难一点

2. 微博类网站

比如 新浪微博
半公开的信息,不登录可以爬取少量信息,登陆后可以爬取大量信息
有一些反爬策略,反爬策略稍微复杂,User-Agent检测、Referer检测、Cookie验证、IP限制频次。需要伪装User-Agent、Referer、Cookie、要使用代理

3. 猫眼类网站

比如 猫眼
能爬取,但是爬取到的信息要经过处理
要用到图像处理

4. 携程类网站

比如 携程、去哪儿、裁判文书
公开的信息,不登录可以爬取。如果获取少量信息不难,但是要爬取数量上万,有难度。
反爬策略较难,User-Agent检测、Referer检测、Cookie验证、加密js、IP限制频次、参数动态变化、返回的结果还需要处理(字符拼接、图像识别)
裁判文书的反爬策略是,1.首先用post请求(太可气了) 2.guid 随机生成 3. number 每次变化 4. 混淆加密js 5. 图形验证码 6.IP限制 7.漫长的等待(文书呀,你们是技术不行还是故意要拖延时间,就查一页,你让我等这么久) 8.抽风的结果 即使你所有参数都对,偶尔也给你来个查不到内容
携程的js动态变化

5. 工商类网站

比如天眼查
算是公开的信息
反爬策略特别难,User-Agent检测、Referer检测、登录及Cookie验证、IP限制频次、混淆加密js(不定期更新)、参数动态变化、图形验证码
天眼查 1. User-Agent检测 Referer检测 IP限制频次 这些对天眼查来说简直是小儿科 2.要查询必须登录 2. 混淆加密js 3.参数动态变化 4.不同页面反爬策略不一样 5.对页数进行限制(你只能爬少量数据) 6. 头疼的特别难破的验证码 7. 最难的是,即使你把多有反爬策略都分析出来,你没办法爬到天眼查的全量数据

即使我爬了天眼查的部分数据,但是,论爬虫,我最服天眼查。

PS:天眼查的一条数据可以卖好几块钱,终于知道天眼查的反爬策略为什么这么难了吧。去招聘网站搜一搜天眼查的招聘信息。一个反爬虫工程师 15k-30k,一个月才3W,平摊到每条数据上,连一里都不到。有钱就是任性呀。

2017-06改过一个版,全部使用https,而且反爬策略严了 然后2017年后半年可能又改了几次

而爬虫是可以无限逼近于真人的,比如:

chrome headless或phantomjs来模拟浏览器环境
tesseract识别验证码
代理IP淘宝就能买到
所以我们说,100%的反爬虫策略?不存在的。
更多的是体力活,是个难易程度的问题。

反爬手段举例

自动封/解封ip

discuz论坛,每天有很多注册机注册的用户,然后发垃圾广告帖子。虽然使用了一些插件但没有效果。分析访问日志,发现有几个ip访问量特别大,所以想到可以写个shell脚本,通过分析访问日志,把访问量大的ip直接封掉。
但是这个脚本很有可能误伤,所以还需要考虑到自动解封这些ip。

思路:
1 可以每分钟分析1次访问日志,设定一个阈值,把访问量大的ip用iptables封掉80端口
2 每20分钟检测一次已经被封ip的请求数据包数量,设定阈值,把没有请求的或者请求量很小的解封

#! /bin/bash
## To block the ip of bad requesting.
## Writen by aming 2017-11-18.

log="/data/logs/www.xxx.com.log"
tmpdir="/tmp/badip"
#白名单ip,不应该被封
goodip="27.133.28.101"

[ -d $tmpdir ] || mkdir -p $tmpdir
t=`date -d "-1 min"  +%Y:%H:%M`

#截取一分钟以前的日志
grep "$t:" $log > $tmpdir/last_min.log

#把一分钟内日志条数大于120的标记为不正常的请求
awk '{print $1}' $tmpdir/last_min.log |sort -n |uniq -c |sort -n |tail |awk '$1>120 {print $2}'|grep -v "$good_ip"> $tmpdir/bad.ip
d3=`date +%M`

#每隔20分钟解封一次ip
if [ $d3 -eq "20" ] || [ $d3 -eq "40" ] || [ $d3 -eq "00" ]; then
        /sbin/iptables -nvL INPUT|grep 'DROP' |awk '$1<10 {print $8}'>$tmpdir/good.ip
        if [ -s $tmpdir/good.ip ]; then
        for ip in `cat $tmpdir/good.ip`
        do
                /sbin/iptables -D INPUT -p tcp --dport 80 -s $ip -j DROP
                d4=`date +%Y%m%d-%H:%M`
                echo "$d4 $ip unblock" >>$tmpdir/unblock.ip
        done
        fi
        #解封后,再把iptables的计数器清零
        /sbin/iptables -Z INPUT
fi

if [ -s $tmpdir/bad.ip ] ; then
    for ip in `cat $tmpdir/bad.ip`
    do
        /sbin/iptables -A INPUT -p tcp --dport 80 -s $ip -j DROP
        d4=`date +%Y%m%d-%H:%M`
        echo "$d4 $ip block" >>$tmpdir/block.ip
    done
fi

References

[1] https://segmentfault.com/a/1190000012293292 如果有人问你爬虫抓取技术的门道,请叫他来看这篇文章
[2] http://imweb.io/topic/595b7161d6ca6b4f0ac71f05?from=timeline
[3] https://mp.weixin.qq.com/s/0itKQmk9Z6OPiRqvUkSfUA
[4] https://mp.weixin.qq.com/s/LSSY17QgpA9iwMKAX1As_Q
[5] http://litten.me/2017/07/09/prevent-spiders/ 反击爬虫,前端工程师的脑洞可以有多大?