顶象验证码ac参数,我补到900多字节,它终于不报错...
背景介绍
【验证码开放平台】 - 通过我们的 API 服务和终极一站式解决方案,赋能开发者构建强大的网络爬虫与数据采集项目。
进入正题
这两天跟一个文字点选验证码杠上了,就那种给你一堆乱序的图,让你按顺序点文字的。
问题不大,先得把图给拼回来。官方的玩法是,根据一个captcha_id,生成一个乱序映射的数组,然后按这个数组把切碎的图重新排一遍。
生成那个数组的逻辑,一开始看还有点绕,其实就是把id里的每个字符转成ASCII码,然后对32取模,如果模数冲突了就往后顺延,保证不重复。代码很短,几行搞定:
def get_image_arry(r):
t = []
for e in [ord(i) for i in r]:
while e % 32 in t:
e += 1
t.append(e % 32)
return t
有了这个数组,就相当于有了“图纸”。接下来就是拼图。
这里我踩了个坑,对着“图纸”拼的时候,脑子抽了,把原图的列和要放的位置弄反了。结果拼出来的图,不是字碎了,就是脸歪了,反正人是看不懂的。后来才反应过来,人家告诉你的意思是“乱序图里第c列,应该放在正常图的第xp列”,我给搞成反向映射了。修正之后,图就正常了。拼图代码大概长这样,可以直接用:
def img_recover(self,binary, captcha_id):
# 先拿到还原顺序的数组,restore_list 就是上面那个函数生成的
restore_list = self.get_image_arry(captcha_id)
img = cv2.imdecode(np.array(bytearray(binary), dtype='uint8'), cv2.IMREAD_UNCHANGED)
new_img = np.zeros((150, 288, 3), dtype=np.uint8)
lk = len(restore_list)
ck = int(300 / lk)
for cp in range(lk):
c = restore_list[cp] % lk * ck
xp = cp % lk * ck
slice_img = img[0: 150, c: c + ck]
new_img[0: 150, xp:xp + len(slice_img[0])] = slice_img
new_img = cv2.resize(new_img, (300, 150))
normal_img = cv2.imencode('.jpg', new_img)[1]
normal_img = np.array(normal_img).tobytes()
return normal_img
图拼好了,我以为最难的部分过去了,结果噩梦才刚开始——那个叫ac的加密参数。
一开始我生成的ac,长度才153。真的,就153个字符。然后奇葩的是,在某些站点,这么短的玩意儿,它竟然也能过!那种感觉就像你去面试,穿个拖鞋大裤衩,结果面试官还给你发offer了,离谱。
但碰到像海航那种比较严格的站点,直接就给我踹回来了,死活过不去。因为原版官方的ac,长度是一千多啊……
这明显是greenseer里面缺浏览器环境,很多东西没补上。没办法,缺啥补啥呗,打补丁的日子就这么开始了。
补屏幕分辨率、补Canvas指纹、补WebGL、补字体列表、补插件……各种补。真的是缝缝补补又一年。中间好几次想直接摆烂,不干了,一想到“兄弟,你这个ac太短了”的嘲讽,就又咬着牙继续加。
最后,终于把长度从153,怼到了900多。虽然跟官方的1000多还差那么一百来字节,但实测下来,基本能通用了。当我看到那个请求终于返回200,验证通过的绿勾出现时,心里只有一句话:这玩意儿,真的不能太短,太短了真会被看不起。
最后,关于constid和ac的生成逻辑,之前的文章里都写过,直接搬过来改改参数就能用。
总结
这篇文章其实也没啥高深的,就是记录一下。希望兄弟们少走点弯路,尤其是那个拼图顺序的坑和ac长度的坑,一定要注意。
更多推荐


所有评论(0)