用Python实现滑动验证码的方法和代码是什么
Admin 2022-05-23 群英技术资讯 872 次浏览
点击滑动按钮,将发送一个请求到 /zfcaptchaLogin
请求内容
"type": "verify" "rtk": "6cfab177-afb2-434e-bacf-06840c12e7af" "time": "1624611806948" "mt": "W3sieCI6OTY1LCJ5IjoxNjksInQiOjE2MjQ2MTE4MDY4Njh9LHsieCI6OTY1LCJ5IjoxNjksInQiOjE2MjQ2MTE4MDY5NDh9XQ==" "instanceId": "zfcaptchaLogin" "extend": "eyJhcHBOYW1lIjoiTmV0c2NhcGUiLCJ1c2VyQWdlbnQiOiJNb3ppbGxhLzUuMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMF8xNV83KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvOTEuMC40NDcyLjEwNiBTYWZhcmkvNTM3LjM2IiwiYXBwVmVyc2lvbiI6IjUuMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMF8xNV83KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvOTEuMC40NDcyLjEwNiBTYWZhcmkvNTM3LjM2In0="
通过 base64 解密 mt和 extend 得出解密的数值
# mt [{"x":965,"y":169,"t":1624611806868},{"x":965,"y":169,"t":1624611806948}] # extend {"appName":"Netscape","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36","appVersion":"5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36"}
mt 为用户的点击行为,x为X轴上的值,y为Y轴上的值,t为时间戳。通过大量点击分析,发现x值最小值为 950,得出950 为 X轴的起点,y值随机无固定值。
extend 为请求头部内容
将图像灰度化,通过getpixel可以获取图像某一点的颜色值, 颜色值越高代表图像越浅,所以寻找纵向连续50个像素点均是 getpixel(x+1, y) > getpixel(x, y)(X轴=x 比 X轴=x+1 颜色浅)
并扫描图像,当x=130、扫描高度=50时,的颜色比x+1时深。
from PIL import Image import matplotlib.pyplot as plt import numpy as np scanf_height= 50 # 扫描的高度 img = Image.open("zfcaptchaLogin.png") def contrast(imgl, x, y,scanf_height): # 黄框颜色值比红框颜色值浅的个数 count = 0 for i in range(scanf_height): if imgl.getpixel((x+1, y+i)) > imgl.getpixel((x, y+i)): count += 1 # 当 count = scanf_height, 代表黄条区域 整体 红条区域 颜色值浅,则是验证码框位置 return count def scanf(img): imgx, imgy = img.size imgl = img.convert('L') # 图像灰度化 plt.yticks([]) plt.xticks([i for i in range(0, imgx, 25)]) plt.imshow(img) plt.pause(0.5) for y in range(0, imgy-scanf_height, 10): plt.pause(0.01) plt.clf() plt.yticks([]) plt.xticks([i for i in range(0, imgx, 25)]) plt.imshow(imgl, cmap=plt.cm.gray) for x in range(1, imgx-1, 1): plt.pause(0.0001) plt.plot([x-1,x-1], [y, y+scanf_height], color='white') plt.plot([x,x], [y, y+scanf_height], color='red') plt.plot([x+1,x+1], [y, y+scanf_height], color='yellow') count = contrast(imgl, x,y, scanf_height) plt.title('count: {}'.format(count) ) print("x,y=[{}, {}], 黄条区域值比红条区域颜色值浅的个数:{}".format(x,y, count)) if count == scanf_height: return scanf(img) plt.show()
优化代码计算x,y值
import json import random import time from io import BytesIO from PIL import Image class ZfCaptchaRecognit(object): def __init__(self, img_path): self.img = Image.open(img_path) def _get_xy(self): # 计算 x,y 值 def _is_dividing_line(img_l, x, y): for n in range(50): # 寻找纵向连续50个像素点均是 X=x 比 X=x+1 颜色深 if y + n >= img_l.size[1] or x >= img_l.size[0] - 1: return False if img_l.getpixel((x + 1, y + n)) - img_l.getpixel((x, y + n)) < 2: return False return True img_l = self.img.convert("L") for x in range(img_l.size[0]): for y in range(img_l.size[1]): if _is_dividing_line(img_l, x, y): return (x, y) def show_tag(self): # 展示 切分点 X, Y = self._get_xy() img2 = Image.new("RGB", self.img.size, (255, 255, 255)) for x in range(self.img.size[0]): for y in range(self.img.size[1]): pix = self.img.getpixel((x, y)) img2.putpixel((x, y), pix) if x == X or y == Y: img2.putpixel((x, y), 225) img2.save("show_tag.png") img2.show() captcha = ZfCaptchaRecognit("zfcaptchaLogin.png") captcha.show_tag()
通过 步骤一得出x值最小为950,y值无规律
则提交参数mt的大致格式数据是
[{ "x":950+ 滑动距离 + 浮动值, # 浮动值的范围通过分析提交参数得出在10~20内 "y":random.randint(150, 190), # 无规律,暂定150到190范围内 "t":int(time.time() * 1000)}, # 时间戳 ...]
获取mt 参数
import json import random import time from io import BytesIO from PIL import Image class ZfCaptchaRecognit(object): def __init__(self, img_stream): obj = BytesIO(img_stream) self.img = Image.open(obj) def _get_xy(self): ... def generate_payload(self): base_x = 950 X, Y = self._get_xy() payloads = [{"x": base_x + random.randint(5, 20), "y": random.randint(150, 190), "t": int(time.time() * 1000)}] for i in range(random.randint(15, 30)): # 在上一个参数基础下浮动 last_payload = payloads[-1].copy() payloads[0]["x"] += random.choice([0] * 8 + [1, -1] * 2 + [2, -2]) last_payload["t"] += random.randint(1, 20) last_payload["y"] += random.choice([0] * 8 + [1, -1] * 2 + [2, -2]) payloads.append(last_payload) payloads[-1]["x"] = base_x + random.randint(10, 20) + X return json.dumps(payloads) captcha = ZfCaptchaRecognit("zfcaptchaLogin.png") captcha. generate_payload()
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
用python怎样实现图片转字符画的效果?相信不少朋友应该都有看过用一些字符组成起来图片的,放大来看是一个字符,全图来看又是一副完整图片,是不是很有意思呢?那么这样的效果是怎样实现的呢?下面和小编一起来看看吧。
这篇文章主要介绍了Python实战之实现简单的名片管理系统,文中有非常详细的代码示例,对正在学习python的小伙伴们有非常好的帮助,需要的朋友可以参考下
这篇文章主要为大家介绍了python密码学RSA算法及秘钥创建教程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
Python内置函数-next() 函数。next() 返回迭代器的下一个项目。next() 函数要和生成迭代器的iter() 函数一起使用。
这篇文章主要介绍了Python Asyncio调度原理详情,Python.Asyncio是一个大而全的库,它包括很多功能,而跟核心调度相关的逻辑除了三种可等待对象外,还有其它一些功能,它们分别位于runners.py,base_event.py,event.py三个文件中
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008