概述
之前在知乎上看到有人分享的一个有趣的反爬策略:
那个变态混淆页面源码是这个样子的,正文内容穿插在混淆元素中:
看到这么变态的页面结构很感兴趣于是就尝试解析了一下。
知乎分享地址:有哪些有趣的反爬虫手段? - 阿阿聪的回答 - 知乎
微信变态混淆页面地址:过年同学聚会,到底该不该去?
分析 & 实现
对于这种一般都是在选择器中过滤掉不可见的元素就可以了,对于不可见元素目前遇到过并解决掉的两种情况:
1. 通过display:none;来隐藏(全网代理公开ip爬取(隐藏元素混淆+端口加密))
2. 通过透明度和偏移来隐藏,比如opacity: 0;虽然元素透明了但是在盒子模型中还是占用了空间的,会把旁边挤开太明显了所以就需要再margin偏移一下将其占用空间释放掉。
实际上两种方式还是有区别的,display:none;的内容复制不会被影响,复制到的是看到的内容,opacity:0; 并偏移的复制的话会把混淆元素的内容也带上,复制到的并不是看到的内容。
这个微信页面就是第二种方式,来看下它的套路:
<span style="margin-right: -1em; max- 100%; opacity: 0; box-sizing: border-box !important; word-wrap: break-word !important;">钔</span>
先通过opacity:0;将自己变成透明的,然后使用margin-right:-1em;将占用的位置腾出来。
思路就是遍历整个DOM树手动过滤收集,下面是一个简单的实现,只是将文本内容抓取没有保存样式和图片:
""" 微信不可见元素混淆页面内容解析 https://mp.weixin.qq.com/s?__biz=MzI0MDYwNjk2OA==&mid=2247484365&idx=4&sn=291a93e8a4ce6e90d3b6ef8b98fe09c4&chksm=e919085ade6e814cc037ecf6a873f22da0e492911a4e539e6f8fdeff022806b4d248c4d54194&scene=4 """ import requests import bs4 def get_html(url): return requests.get(url).content.decode('UTF-8') def dfs_extract_text(tag): result_content = '' for child in tag.contents: if type(child) == bs4.NavigableString: result_content += child elif 'style' not in child.attrs or 'opacity: 0;' not in child.attrs['style']: # 过滤掉透明元素,要么没有style属性,要么style属性中不包含透明样式,否则认为是透明元素直接忽视掉 result_content += dfs_extract_text(child) return result_content def parse(url): html_content = get_html(url) page = bs4.BeautifulSoup(html_content, 'html.parser') content_panel = page.find(id='js_content') return dfs_extract_text(content_panel) if __name__ == '__main__': target_url = 'https://mp.weixin.qq.com/s?__biz=MzI0MDYwNjk2OA==&mid=2247484365&idx=4&sn=291a93e8a4ce6e90d3b6ef8b98fe09c4&chksm=e919085ade6e814cc037ecf6a873f22da0e492911a4e539e6f8fdeff022806b4d248c4d54194&scene=4' content = parse(target_url) print(content)
程序运行结果:
昨晚回来晚了,是因为我去参加了一个同学聚会,回来后已经夜里十一点多了。这个聚会:并没有想象中那么亲近,也没有传说中的那么美好,更没有当年时的那种纯粹。给我整体的感觉就是六个字:人很累,心很悲 !原因有三个:第一个原因: 你念念不忘的过去,别人已经忘得一干二净了。我和一个女同学上学时很要好(也许只是我的以为,她未必这么认为),那时因为学校离家远,中午放学我们都不回家,就在学校里吃点从家里带来的饭菜。多年以来,和她之间在我脑海中最清晰的画面,就是吃过简单凑合的午饭,我们手牵手围着硕大的操场一圈又一圈的走,有时谈笑,有时打闹,有时就那么静静,静静的牵手走着……昨晚,我向她提起了这段对于我来说,最难忘最深刻最眷恋的记忆。她却给了我最具杀伤力最具毁灭性的一个回答:我都忘了!!!瞬间,我再也没有聊下去的欲望,索然无味……第二个原因: 我们都被经历戴上了面具,被现实披上了虚伪,再也没有上学时的纯粹!尽管是高档的饭店,晶亮的酒杯,我却觉得抵不上年少时你用零花钱买给我的一颗两毛钱的雪糕,一份自己笨手笨脚做的生日礼物。聚会里面有一个同学经历非常坎坷(我们都知道),他却笑得没心没肺,我们明白他在坚强面对。如果和一群老同学,都要装,都要扛,都要说自己无所谓,那还有什么时候,什么朋友,能让一个人打开心扉 ? ?莫名的感到悲哀:曾经的感情只能留给曾经,过去的记忆只能住在过去。老同学之间,没有共同的未来 !第三个原因: 我们都还是原来的那个人,却没有了原来的那颗心。漫长的岁月肯定改变了我们的容貌,不过仔细分辨,我们都能认出来彼此,眉眼,笑容,举止,习惯,年少时的记忆总是那么的深刻,那么的不可磨灭。最可怕的事:不是岁月让一个人变胖了,变老了,变得外表不一样了,而是,它改变了一个人是非分明的心,一个人错对分清的心,一个人向善护弱的心!混得好的,高谈阔论,一大群人追捧围绕着;混得不好的,沉默不语,一大群人敷衍冷淡着!上学时的我们,没有层次,没有高低,没有等级之分的,因为我们是处在同一个起跑线的。现在的我们,再不是当初了……别再妄想着:彼此亲密无间,没有距离,别再奢望着:彼此畅所欲言,没有顾忌!我们说着交际的话,喝着应酬的酒,带着应付的笑,却再也走不进彼此的心……如今的同学聚会,聚的只能是一群的人,而不是一众的心了;如今的同学聚会,聚的只能是外放的笑声,而不是内在的心声了;如今的同学聚会,聚的只能是重逢的酒菜飘香,散场后的感触凄凉 !—《END》—
优点 & 缺点
使用这种方式渲染出的页面,当我复制网页内容并粘贴到别处的时候:
悲剧啊,我复制出来的内容包括了不可见元素的内容,这可以说是一把双刃剑吧,如果作为一个遵纪守法的正常用户我感觉很无辜,为毛我复制到的内容不是我看到的内容呢,这啥破网站啊,这是网站方不希望看到的。但是如果对面的是爬虫的话,一个不小心就会造成这种后果:
这恐怕是网站方喜闻乐见的…
具有同样特性的还有自定义字体反爬,欲知详情且听下回分析。
.