写在这里
hi, 前几天发起了一个 《hi,写了一点解密与一点反爬,爬虫们,来吧,中秋节礼包等你来取》的小活动,详情可以点击链接跳转查看。
活动可以说已经结束了,因为奖品已经被拿走了,仍然可以去玩,这个东西将会挂在我的网站直到服务器没了。本文将发放该活动攻略。
本项目源码已上传至全球最大同性交友网站 [滑稽] https://github.com/yejue/thegame2
攻略开始
第一关 寻找注册地址
难度:★☆☆☆☆
最初的目的是为了好看一点。这里是一个全黑的背景,藏着一个全黑的图片,该图片是篆体的“众里寻他千百度,蓦然回首,那人却在灯火阑珊处”,将鼠标移至相应区域会出现可点击的鼠标样式,点击后会向后端发送一个请求,返回一个 URL 到 console。打开 console 复制补充到地址栏即可,跳转到注册页面。
附注:从登陆开始所有关键操作都对 selenium 进行判断,凡是发现了selenium马上重定向。
这里只要打开开发者工具就会遇到一个全局都有的JS断点,一定程度造成干扰。只需要点击 Deactive breakpoints 即可取消断点。
第二关 注册
难度:★☆☆☆☆
主要在于寻找图形验证码,图形验证码是一张随机的纯色图片,这并不是错误。将图片下载下来,使用utf8编码解码,会出现的问题是使用utf8对图片解码会出现错误,只需无视错误即可解出正确的验证码。代码如下所示。提交后收到邮箱验证码邮件,复制即可注册。
with open('1.png', 'rb') as f:
a = f.read()
print(a.decode('utf8', errors='ignore'))
第三关 爬取
难度:★★★☆☆
还是老样子,黑色背景,藏着四个窗口,其中第一个窗口为数据页,第四个窗口为数据提交的跳转页,剩余两个是为了凑数。
首先查看需要爬取的是诸如 {‘0’: ‘一’} 的数据,共有11条,剩余1000 条为假数据。使用的是 slick 旋转木马插件,每次滑到最后一页时更新数据,并自动滚回了第5页。因为数据量小,限制一下手工爬取。当然,足够耐心还是可以获得的。
之后是制定爬行策略,我选择的是爬接口。每一次请求有5页的数据,每一条数据有 data_index 和 encrypt_data 这两个键,从返回的 json 可以看到总共的页数,可以很便捷地使用这个数字来遍历取值。
有几点注意事项:
- 后端会对request请求进行甄别,主要在于 Accept,Accept-Language,User-Agent 以及 Referer 这几个请求键。将一个正常的 headers 复制使用即可。
- 后台访问频率限制在 2s/次,小于 2s 时返回一个与原页面一样的蜜罐页,当然,多了一只皮卡丘字符画,并返回418状态码,稍微提示一下这是个蜜罐。
for i in range(203):
req = requests.get(url.format(i), headers=headers)
jsd = json.loads(req.content.decode('utf8'))
for j in jsd['data']['spider']:
if j['data_index'] != '假的':
print(j['encrypt_data'], j['data_index'])
time.sleep(2.1)
爬行完成后,根据序号排列,得到这样的数据。
C₺5ⱴs囿s朊及斲并
从前面的假数据来看,这个encrypt_data 与假数据是对不上的,比如对比前端数据,“极目远望” 对应的是 “枃盰连朝”。这里可以自己使用 ord 寻找规律,也可以考虑前端收到数据后发生了什么变化。
查看对应 JS,发现是混淆压缩过的,复制到一个 JS 解密工具,解密后查看 ajax 处代码,会清晰地看到此处的接收数据后是对其 Unicode 数值做了简单的减法。
将得到的数据 Unicode 值 -2 后得到如下字符串,已经很接近了。
A₸3Ⱳq国q月又新年
接下来是看 A 这个字,在0号位,对应着一个中文“一”,但在源代码中确确实实是 “ A”,这是JS实现不了的。并且从第3页和第13页的页码可以看到 “3” 显示的是“三”。所以考虑是字体做了手脚,也就是字体反爬了。
在页面看到 font-family 使用的是 Arial g,根据 font-face 在数据包中找到字体 arial.ttf,明显不对劲。
将字体下载下来后使用字体编辑工具打开,根据 A₸3Ⱳq国q月又新年 的Unicode 值找到对应被修改的字,依次排开得到一句话:一别三季,庆国庆月又新年。意思是疫情的原因三季一转眼就过去了,马上也能迎来新的一年了,期待有新的开始。祝福各位。