抖音小店、巨量登入,滑动验证码识别

本文介绍了如何使用Python的selenium、pandas、numpy和opencv库自动化破解字节跳动巨量纵横平台的滑动验证码。通过图像处理找到缺口位置,利用Prewitt卷积核突出缺口边缘,最终通过拟合算法校正偏差并控制浏览器完成验证。代码已上传至GitHub,适用于处理类似验证码的自动化场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天的目标地址是字节的巨量纵横,目前在一家广告营销型的公司,专注于在各大平台投放信息流广告。巨量纵横为字节跳动的广告平台,用于管理推广账户。今天破解一下这个平台的登陆入口,为今后的数据爬取开个头。

抖音旗下很多平台都用的是这个验证方式,包括巨量,抖店等平台,均可以使用下面这种方式。

涉及工具技术

  • selenium
  • pandas
  • numpy
  • opencv
  • Pillow
# python 库安装
pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

开始

滑动验证码就是上图这种东西,验证方式就是用鼠标拖动到缺口阴影位置松手即可。

逻辑比较简单,目前要处理的核心问题就是怎么找到这个阴影位置,因为可能有不同的图片而且图片中缺口阴影的位置也不确定。

问题可以简化为:如何找到背景图中缺口的准确位置

分析

首先通过浏览器检查工具,看一下能获得哪些信息。

首先可以获得滑块和缺口图片的链接,还可以获取滑块图片的高度

我们先将缺口图片下载下来,通过简单的图像变换看一下有什么特征可以利用。下面Python代码可用于下载图片。

from urllib import request

img = 'https://p6-catpcha.byteimg.com/tos-cn-i-188rlo5p4y/7fcb5c88410943579af133942e8f9249~tplv-188rlo5p4y-2.jpeg'

request.urlretrieve(img, './img.jpg')

将图片保存下来之后,使用较为通用的处理方法先观察一下图片特点,首先灰度处理,再手动调整阈值观察二值化后的图片。

通过观察可以发现带缺口图片附近有一圈白色痕迹,我们就是要获取到白色方框的左半部分距离整个图片左边的距离。

通过观察二值化后的图片特征,我想到一个办法,就是通过这张二值化后的图片,遍历每一个像素点,找到连续的、在垂直方向均为白色的位置。理论上是可行的,可能验证码图片样本不够,可能会有些图片白色部分较多,比如这张银色的车,白色的色块就比较多。

滤波

因为我们只需要缺口的左边位置的坐标,所以可以通过具有提取边缘特征的水平梯度Prewitt卷积核来处理图片。通过测试我选取了下面这个3x3的卷积核。

⎡⎣⎢⎢111000−2−2−2⎤⎦⎥⎥[10−210−210−2]

通过opencv库处理原图,可以发现图片缺口左边部分的边缘被突出显示了出来。

结果

有了如上的矩阵就简单了,按照之前的思路,找到垂直方向的白线就可以拿到缺口的坐标。

遍历图片每一个点,将白色点的x坐标存入一维数组中,再求该数列的众数就能得出缺口的坐标啦!

偷个懒,众数的不优雅表达
pd.Series(np.array(res_list)).mode()[0]

切图

为了更高的准确率,我们之前还能拿到滑块图片的高度,我们可以将验证码无用部分,也就是缺口部分上下方图片切除掉。

可以通过selenium库 img.value_of_css_property("top") 方法获取页面元素属性,拿到滑块图片的高度,通过后面测量,与原图大概是1.65倍(这个不知道是什么单位的倍数,下面会展示计算方法),滑块高度大约110像素。numpy切片的代码就不放了。切出来的图片类似这样,再进行上面的操作,脑补是能减少误判(没测过😊)

控制浏览器

核心难点突破之后就简单多了,使用selenium这个库来控制浏览器,使用代码的方式操纵鼠标键盘。

拟合

拟合: 形象的说,拟合就是把平面上一系列的点,用一条光滑的曲线连接起来。因为这条曲线有无数种可能,从而有各种拟合方法。拟合的曲线一般可以用函数表示,根据这个函数的不同有不同的拟合名字。

程序计算出的缺口位置,和页面上滑块移动的位置有偏差。拖动滑块位置并通过浏览器控制台可以看到滑块贴合缺口时对应的移动位置。

我收集了几组页面滑块位置与程序计算的位置。(可能有点多)

页面(y)程序(x)
246407
190315
221366
190316
97164
152255
241398
226374

不知道页面和程序输出的为啥相差这么多,可能两数是有什么关系,但是看不懂前端代码,也懒得分析,就假设几个未知数,解一下方程吧。

假设 二元一次方程

𝑦=𝑎𝑥+𝑏y=ax+b

或者 二元二次方程

𝑦=𝑎𝑥2+𝑏𝑥+𝑐y=ax2+bx+c

,我记得次方越高,拟合的就会越好。 最后按一元一次解得 a=1.65

控制浏览器

这部分要使用selenium库,控制浏览器,我使用的是Chrome,关于如何安装selenium以及Chrome控制器驱动程序chrome driver,可以参考百度或者csdn帖子

需要查看自己电脑上的chrome版本和chrome driver的版本一致。

 

源码

本文代码已上传至github,欢迎交流与star。

未完待续...

### Python店API集成的资料及示例 #### 背景介绍 店作为电商的重要组成部分,提供了丰富的API接口供开发者使用。通过这些API,可以实现商品管理、订单处理、库存同步等功能。Python作为一种灵活的语言,能够轻松完成与店API的对接。 --- #### 店API基础概念 店API通常基于HTTP协议,支持RESTful风格的接口设计。开发人员可以通过发送GET、POST等请求来访问相应的资源。为了安全起见,店API需要OAuth 2.0授权机制[^3]。 以下是几个核心的概念: - **App Key 和 App Secret**: 这些是由店平台分配给应用的身份标识符。 - **Access Token**: 应用程序在调用受保护资源之前必须先获取此令牌。 - **Refresh Token**: 当Access Token过期时用于重新生成新的Token。 --- #### 示例代码:获取Access Token 以下是一个完整的Python脚本,演示如何利用`requests`库向店服务器申请Access Token: ```python import requests def get_access_token(app_key, app_secret): url = "https://open.douyin.com/oauth/access_token/" payload = { 'client_key': app_key, 'client_secret': app_secret, 'code': '<your_code>', # 替换为实际的授权码 'grant_type': 'authorization_code' } headers = {'Content-Type': 'application/x-www-form-urlencoded'} response = requests.post(url, data=payload, headers=headers).json() if 'access_token' in response: return response['access_token'] else: raise Exception(f"Failed to retrieve access token: {response}") # 测试函数 try: ACCESS_TOKEN = get_access_token('<your_app_key>', '<your_app_secret>') print("成功获取到 Access Token:", ACCESS_TOKEN) except Exception as e: print(e) ``` --- #### 查询商品列表 一旦获得了有效的Access Token,就可以进一步查询店铺内的商品信息。这里提供了一个简单的例子说明如何拉取商品详情: ```python def fetch_product_list(access_token, page_size=10, page_no=1): url = "https://open.douyin.com/goods/v1/item/list" params = { 'access_token': access_token, 'page_size': page_size, 'page_no': page_no } response = requests.get(url, params=params).json() if response['error'] == 0 and 'data' in response: items = response['data']['items'] for item in items: print(item['item_id'], item['title']) else: print("Error fetching product list:", response) fetch_product_list(ACCESS_TOKEN) ``` --- #### Flask 实现本地服务端接收回调通知 如果希望构建自己的后台系统以接受来自店的通知消息,则可考虑采用Flask框架搭建简易Web Server。如下所示即为此类场景下的基本架构: ```python from flask import Flask, request, jsonify app = Flask(__name__) @app.route('/douyin/callback', methods=['POST']) def douyin_callback(): json_data = request.json event_type = json_data.get('event_type') order_info = json_data.get('order_info') print(f"Received callback with type {event_type}: {order_info}") return jsonify({"status": "success"}), 200 if __name__ == '__main__': app.run(debug=True, port=5000) ``` --- #### 常见问题排查 当尝试连接至店API时可能会遇到一些常见错误情况及其解决办法包括但不限于以下几个方面: - 如果收到401 Unauthorized状态码,请确认所使用的Access Token是否仍然有效以及权限范围设置正确与否[^4]。 - 遇到签名验证失败的情况则需仔细核对时间戳参数timestamp是否超出允许误差区间,并确保加密算法一致。 ---
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sajor_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值