Python破解BiliBili滑块验证码的思路详解(完美避开人机识别)
准备工作
B站登录页https://passport.bilibili.com/login
python3
pipinstallselenium(webdriver框架)
pipinstallPIL(图片处理)
chromedriver:http://chromedriver.storage.googleapis.com/index.html
firefoxdriver:https://github.com/mozilla/geckodriver/releases
B站的滑块验证码如上。
这类验证码可以使用selenium操作浏览器拖拽滑块来进行破解,难点两个,一个如何确定拖拽到的位置,另一个是避开人机识别(反爬虫)。
确定滑块验证码需要拖拽的位移距离
有三种方式
- 人工智能机器学习,确定滑块位置
- 通过完整图片与缺失滑块的图片进行像素对比,确定滑块位置
- 边缘检测算法,确定位置
各有优缺点。人工智能机器学习,确定滑块位置,需要进行训练,比较麻烦,也可以看是否存在在线api可以调用。以下介绍其他两种方式。
对比完整图片与缺失滑块的图片
|仅介绍,本文不进行实现。对于B站来说,是准确率最高的方式(100%),但不能保证未来B站的滑块验证升级,导致不可用。
B站的滑块验证模块,一共有三张图片:
完整图、缺失滑块图、滑块图,都是由画布绘制出的。类似于:
完整图:
HTML代码类似于:
只需要通过selenium获取画布元素,执行js拿到画布像素,遍历完整图和缺失滑块图的像素,一旦获取到差异(需要允许少许像素误差),像素矩阵x轴方向即是滑块位置。
另外由于滑块图距离画布坐标原点有距离,还需要减去这部分距离。
最后使用selenium拖拽即可。
边缘检测算法,确定位置
|滑块基本上是个方形,通过算法确定方形起始位置即可。
- 滑块是方形的,存在垂直的边,该边在缺失滑块图中基本都是灰黑的。遍历像素找到基本都是灰黑的边即可。
- 缺失滑块图中滑块位置是灰黑封闭的。通过算法可以找到封闭区域,大小与滑块相近,即是滑块需要拖拽到的位置。
第二种实现起来有些复杂,不进行实现了。
下面是第一种实现方式,会存在检测不出或错误的情况,使用时需要换一张验证码。也可能存在检测出的边是另一条(因为B站的滑块不是长方形,存在弧形边),那么需要减去滑块宽度
classVeriImageUtil():
def__init__(self):
self.defaultConfig={
"grayOffset":20,
"opaque":1,
"minVerticalLineCount":30
}
self.config=copy.deepcopy(self.defaultConfig)
defupdateConfig(self,config):
#temp=copy.deepcopy(config)
forkinself.config:
ifkinconfig.keys():
self.config[k]=config[k]
defgetMaxOffset(self,*args):
#计算偏移平均值最大的数
av=sum(args)/len(args)
maxOffset=0
forainargs:
offset=abs(av-a)
ifoffset>maxOffset:
maxOffset=offset
returnmaxOffset
defisGrayPx(self,r,g,b):
#是否是灰度像素点,允许波动offset
returnself.getMaxOffset(r,g,b)=255*self.config["opaque"]
defgetVerticalLineOffsetX(self,bgImage):
#bgImage=Image.open("./image/bg.png")
#bgImage.im.mode='RGBA'
bgBytes=bgImage.load()
x=0
whilex=self.config["minVerticalLineCount"]:
#连续多个像素都是灰度像素,直线
#print(x,y)
returnx
y+=1
x+=1
pass
if__name__=='__main__':
bgImage=Image.open("./image/bg.png")
veriImageUtil=VeriImageUtil()
#veriImageUtil.updateConfig({
#"grayOffset":20,
#"opaque":0.6,
#"minVerticalLineCount":10
#})
bgOffsetX=veriImageUtil.getVerticalLineOffsetX(bgImage)
print("bgOffsetX:{}".format(bgOffsetX))
总结
以上所述是小编给大家介绍的Python破解BiliBili滑块验证码的思路详解(完美避开人机识别),希望对大家有所帮助!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。