Python破解BiliBili滑块验证码的思路详解(完美避开人机识别)

这篇文章主要介绍了Python破解BiliBili滑块验证码的思路,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

准备工作

B站登录页 https://passport.bilibili.com/login

python3

pip install selenium (webdriver框架)

pip install PIL (图片处理)

chrome driver:http://chromedriver.storage.googleapis.com/index.html

firefox driver:https://github.com/mozilla/geckodriver/releases

B站的滑块验证码如上。

这类验证码可以使用 selenium 操作浏览器拖拽滑块来进行破解,难点两个,一个如何确定拖拽到的位置,另一个是避开人机识别(反爬虫)。

确定滑块验证码需要拖拽的位移距离

有三种方式

人工智能机器学习,确定滑块位置

通过完整图片与缺失滑块的图片进行像素对比,确定滑块位置

边缘检测算法,确定位置

各有优缺点。人工智能机器学习,确定滑块位置,需要进行训练,比较麻烦,也可以看是否存在在线api可以调用。以下介绍其他两种方式。

对比完整图片与缺失滑块的图片

| 仅介绍,本文不进行实现。对于B站来说,是准确率最高的方式(100%),但不能保证未来B站的滑块验证升级,导致不可用。

B站的滑块验证模块,一共有三张图片

完整图、缺失滑块图、滑块图,都是由画布绘制出的。类似于:

完整图:

缺失滑块图:

滑块图:

HTML代码类似于:

只需要通过selenium获取画布元素,执行js拿到画布像素,遍历完整图和缺失滑块图的像素,一旦获取到差异(需要允许少许像素误差),像素矩阵x轴方向即是滑块位置。

另外由于滑块图距离画布坐标原点有距离,还需要减去这部分距离。

最后使用 selenium 拖拽即可。

边缘检测算法,确定位置

| 滑块基本上是个方形,通过算法确定方形起始位置即可。

介绍两种方式

滑块是方形的,存在垂直的边,该边在缺失滑块图中基本都是灰黑的。遍历像素找到基本都是灰黑的边即可。

缺失滑块图中滑块位置是灰黑封闭的。通过算法可以找到封闭区域,大小与滑块相近,即是滑块需要拖拽到的位置。

第二种实现起来有些复杂,不进行实现了。

下面是第一种实现方式,会存在检测不出或错误的情况,使用时需要换一张验证码。也可能存在检测出的边是另一条(因为B站的滑块不是长方形,存在弧形边),那么需要减去滑块宽度

class VeriImageUtil(): def __init__(self): self.defaultConfig = { "grayOffset": 20, "opaque": 1, "minVerticalLineCount": 30 } self.config = copy.deepcopy(self.defaultConfig) def updateConfig(self, config): # temp = copy.deepcopy(config) for k in self.config: if k in config.keys(): self.config[k] = config[k] def getMaxOffset(self, *args): # 计算偏移平均值最大的数 av = sum(args) / len(args) maxOffset = 0 for a in args: offset = abs(av - a) if offset > maxOffset: maxOffset = offset return maxOffset def isGrayPx(self, r, g, b): # 是否是灰度像素点,允许波动offset return self.getMaxOffset(r, g, b) = 255 * self.config["opaque"] def getVerticalLineOffsetX(self, bgImage): # bgImage = Image.open("./image/bg.png") # bgImage.im.mode = 'RGBA' bgBytes = bgImage.load() x = 0 while x = self.config["minVerticalLineCount"]: # 连续多个像素都是灰度像素,直线 # print(x, y) return x 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滑块验证码的思路详解(完美避开人机识别),希望对大家有所帮助!

相关文章

功能概要:(目前已实现功能)公共展示部分:1.网站首页展示...
大体上把Python中的数据类型分为如下几类: Number(数字) ...
开发之前第一步,就是构造整个的项目结构。这就好比作一幅画...
源码编译方式安装Apache首先下载Apache源码压缩包,地址为ht...
前面说完了此项目的创建及数据模型设计的过程。如果未看过,...
python中常用的写爬虫的库有urllib2、requests,对于大多数比...