爬虫与汽车之家的Css:Content-反爬与反反爬的奇技淫巧

大家好,我又要食言了,总盯着去哪儿挺没意思的,今天咱们先聊另外一个老朋友-汽车之家。

先上广告,土豪朋友不想写代码的,可以直接使用我们的汽车之家论坛爬虫:

汽车之家论坛采集爬虫-神箭手云

给新朋友的之前的文章列表:

爬虫被封IP了怎么办-反爬与反反爬的奇技淫巧

爬虫中的验证码识别-反爬与反反爬的奇技淫巧

爬虫中Cookie的伪造(非登录)-反爬与反反爬的奇技淫巧

爬虫与诡异的字体-反爬与反反爬的奇技淫巧

话说感觉这个系列的我起名字越来越不走心了。越写越像哈利波特的起名套路了-爬虫与混血王子。(嗯,一点都不违和)我这个爱扯犊子的性格真是很难收敛啊。

话说Css自从越来越强大之后,被很多反爬工程师看上了。上篇文章介绍的字体就需要用到Css中的font-face和font-family。这节我们通过汽车之家来看看Css在反爬中另外一个妙用-content。

本来网页上显示的字无非两种,一种就是文本,一种就是显示在图片上的。所以之前有一种常规的反爬,就是把字当做图片替换来显示,目前百度还经常喜欢这么处理,比如百度知道,百度指数(参考天坑),当然不少的电话号码和邮箱这类重要信息,依然也再沿用这个方案。

然后随着css的content兼容性越来越好之后,就又有了一个性能更好的反爬,就是用css的content来代替原来文本中的文字,辅以合适的随机生成的方法,确实也不错。算是一个性能和反爬折中的方案吧,比如我们今天要提到的 汽车之家论坛 就是采用这样一个反爬方案。

一.为什么Css:Content能反爬。

事实上任何能让原来html中文本隐藏混淆加密又不影响正常用户显示的方式都可以来做反爬,比如我们上一篇文章提到的字体方式混淆,比如我们后面要提到的JS加密。而这篇文章主要是采用Css的content属性来隐藏。

我们简单的看下content属性使用,大家可以尝试复制这段写入一个网页的Css中

div:before {
   content: "神箭手";
}

我们会发现每一个div的开头都加入的神箭手的文字,而且这些文字还是无法复制的。再加上并不像生成图片那样会严重拖慢服务器性能,所以算是一个挺折中的方案。

二.如何好好利用Css:Content反爬

我们一起来看看汽车之家的反爬学习一下:

我们打开一个汽车之家论坛网页,然后直接Ctrl+A全选,就可以很明显的看到用Css的Content插入进的字符,我们掀开被子仔细研究下:

可以看到,汽车之家是将一些常用的字,包括<了><,><的><九>等等变换成Css,这样做优点是可以提前写好css,缺点是由于是固定的库,很容易先把映射的关系解析好,然后直接全文替换。因此比较推荐的,当然还是每次的动态生成,不过这依然产生一个工程性的优化问题,这里还是比较推荐用池的方案,或者用客户的IP做一个hash映射也不错。

不过汽车之家做的比较好的在于很好的隐藏了这段固定映射的Css,同时Css中的class也每次会替换一些名称部分,同时又不是每次都把所有的映射库输出出来,而是节选文章中有的文字,因此既缩小了输出大小,又隐藏了整体库,看得出工程师也是打得一手好牌啊。

三.如何应对Css:Content这种类型的反爬

我们就以汽车之家为例吧:

1.获取映射的Css

其实汽车之家这个例子来说,主要的问题并不是如何解决这种反爬,因为这种模式的反爬如果知道映射,搞起来太简单,直接正则替换就行了。这里最难的是怎么找到这个映射,汽车之家可以说隐藏的是教科书级的完美,解析方案我就不展开讲了,因为这个是Javascript对抗里的内容(后面我可能会拿出几篇文章单独讲JS对抗),重点就是解析跟在正文后面的这一段JS。

好的工具等于成功的一半,想要很好的解析JS,一定要有一个好的JS解释引擎。这样可以省掉大量的破解的工作而直接运行别人的JS,在代码中整合脚本引擎相当麻烦,最完美的莫过于找一个好的JS的爬虫框架。

具体的Javascript对抗我在后面再讲,这里简单说下,直接运行这段代码,我们可以看到在Nl_(可变的)这个变量中存储了完整的Css映射,因此我们想办法在运行中保存该变量,带入下一步即可。

2.根据映射进行内容替换

我们既然拥有了Css映射,那还有啥难的,直接读取CssRules,循环用正则替换把

<span class='hs_kw4_mainYM'></span>

这类标签直接替换成content中的文字:

好了,大功告成。

贴一下部分神箭手中运行的解析代码:

var code = extract(page.raw, "//div[@class='conttxt']/div/script"); if(code){ eval(code); var cssMapping = {}; if(rules.length > 0){ for(var ri in rules){ var rule = rules[ri]; var matches1 = /content:\s*"([^"]+)"/.exec(rule) var matches2 = /\.([^:]+)::before/.exec(rule) if(matches1 && matches2){ cssMapping[matches2[1]] = matches1[1]; } } page.raw = page.raw.replace(/<span\s+class='(hs_kw\d+_[^']+)'><\/span>/g, function(match,p1,p2){ return cssMapping[p1]; }); } } page.raw = exclude(page.raw, "//div[@class='conttxt']/div/script"); 

————————————————最后说两句————————————————————

大家会发现,很多非常奇特的反爬措施,大多依赖Javascript加密的功力。当然有些Javascript加密可以直接通过JS渲染,如[Email Protection],但是也有很多单纯通过渲染JS无法解决,如今天这篇文章中提到,因此也让Css的这种反爬措施有别于普通的JS加密形式,给反反爬工程师设置了更高的障碍,是我个人比较推荐的一种反爬手段。反过来对于反反爬来说:在有了好的工具前提下,熟练掌握JS则是一个必备内功之一。

分享到: