巨某量引擎后台登录实战笔记 | Playwright自动化框架

前言

本文章中所有内容仅供学习交流,抓包内容、敏感网址、数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除!

入正题看看滑块是怎么个事

目标网站:aHR0cHM6Ly9idXNpbmVzcy5vY2VhbmVuZ2luZS5jb20vbG9naW4=

开启F12,选择邮箱登录,邮箱填的简单一点就可以触发滑块验证码,比如"abcabc123456@qq.com"

点击登录后我们就可以看见滑块,观察请求,可以看见是一个"/account_login/v2/..."的请求返回了验证码的一些信息,这个接口实际上就是登录接口,异常就会返回验证码信息。

[显示滑块和接口参数的图片]

分析请求

我们继续看请求,下面有一个"rmc.bytedance.com/verifycenter/captcha/v2/....."的get请求,并且是一个html页面,我们直接双击进去,可以发现这就是滑块验证码本体。这个验证码窗口实际上是内嵌进登录页面的"iframe"中的,那么我们后面的滑动测试和分析都可以单独打开这个页面进行了。

[完成滑动后请求图片]
我们手动滑动测试一下看看它会发送什么请求。

在这里插入图片描述

可以看见有2个请求,请求1(验证是否滑动成功)"/captcha/verify/...";请求2(重新登录)"/account_login/v2/..."。

到这就差不多确定整个流程了:

在这里插入图片描述

了解滑块验证码构成

滑块验证码一般是由滑块角块(也是图片)和背景图片两部分构成,其中滑块背景图片位置是固定的,我们滑动的是滑块角块图片到背景图片缺口位置。

滑块的初始位置一般会是随机的,而巨量(抖音系)的滑块则是固定在最左边,这无形中降低了我们的处理难度,因为不需要去找滑块角块的初始位置。

ddddocr 解决方案

经过测试,发现巨量滑块是可以使用无头浏览器进行处理的,所以我们这里使用ddddocr框架进行图像识别,然后获取滑动距离;使用无头浏览器进行滑块滑动。

所以我们想要实现自动化登录就需要处理几个关键点:

  1. 获取滑块验证码的参数信息。滑块图片、背景图片(如果有滑块验证码)、以及获取滑块的参数(用于验证)。
  2. 使用无头浏览器滑动滑块。

1、获取滑块验证码的参数信息

我们清空缓存,刷新页面重新登录,找到/account_login/v2/...接口,可以看到我们在清空缓存后的第一次请求fp是空的,并且有一个a_bogus参数,account、password是经过一定算法处理的账号和密码。

在这里插入图片描述

然后我们在关闭验证码框,账号密码不变,重新点一次登录,再次观察请求,我们会发现fp参数就不为空了,并且a_bogus也改变了,只有账号和密码还有其他参数没有改变,因此我们可以得出结论:在账号密码不变的情况下,登录接口只有a_bogus和fp参数是动态改变的。

在这里插入图片描述

a_bogus算法处理生成的(这个参数登录接口暂时没有做强校验,如果设置为空后台登录只是会显示未知登录设备,所以暂不处理,后续单独出一篇内容讲解。),而fp参数是由登录接口返回的。

我们在看请求接口"rmc.bytedance.com/verifycenter/captcha/v2/...",可以发现它的请求参数fp、verify_data就是在登录接口中获得到的2个参数,并且其他的参数只有一个时间戳会改变。
我们在手动滑动滑块到正确的位置,可以看见先发送了一个请求/captcha/verify/...这是一个验证是否滑动正确的请求,然后又发送了第二次/account_login/v2/...登录请求,并且这一次的响应不是验证码信息,而是登录成功/密码错误的信息。
那么其实到这我们需要的所有内容就已经得到了。
完整的流程是:先登录获取验证码参数 -> 构造验证码html -> 访问html(滑块图片、背景图片都包含在内) -> 通过无头浏览器去处理滑块。

在这里插入图片描述

2、使用无头浏览器滑动

使用无头浏览器滑动我们需要先获得滑块和目标位置的距离,而巨量这个滑块起点固定在初始的位置,并且没有y轴的需求,所以我们使用ddddocr可以很轻松的得到距离。

import time
import base64
import random
import ddddocr
import requests
from playwright.sync_api import sync_playwright, Pagedef get_img_bytes_by_htmltag_selector(page: Page, selector: str) -> bytes:"""根据浏览器标签id获取图片bytes 数据:param page: page对象:param selector: css选择器 img#captcha-verify_img_slide  表示找img标签id=captcha-verify_img_slide的:return:"""img_bytes = b''if "img" in selector:page.wait_for_selector(selector)img_element = page.query_selector(selector)img_url = img_element.get_attribute('src')img_bytes = requests.get(img_url).contentelif "canvas" in selector:page.wait_for_selector(selector)canvas = page.query_selector(selector)base64_data: str = page.evaluate('(canvas) => canvas.toDataURL("image/jpg")', canvas).replace('data:image/png;base64,', '')img_bytes = base64.b64decode(base64_data)return img_bytesdef get_distance_by_ddddocr(slide_img_bytes, target_img_bytes) -> int:"""通过ddddocr识别到目标图案的坐标:param slide_img_bytes: 小滑块图片字节:param target_img_bytes: 目标背景图片字节:return: 目标图案坐标x轴"""det = ddddocr.DdddOcr(det=False, ocr=False, show_ad=False)res = det.slide_match(slide_img_bytes, target_img_bytes, simple_target=True)target_x = res["target"][0]return target_xif __name__ == '__main__':# 滑块iframe测试链接url_base64='aHR0cHM6Ly9ybWMuYnl0ZWRhbmNlLmNvbS92ZXJpZnljZW50ZXIvY2FwdGNoYS92Mj9mcm9tPWlmcmFtZSZmcD12ZXJpZnlfbHdlejN5ZmdfYmM3YWIxMTRfNGMwOF9lNmU2XzNmZWFfNDc1NzIxM2EwNzE3JmVudj0lN0IlMjJzY3JlZW4lMjIlM0ElN0IlMjJ3JTIyJTNBMTkyMCUyQyUyMmglMjIlM0ExMDgwJTdEJTJDJTIyYnJvd3NlciUyMiUzQSU3QiUyMnclMjIlM0ExOTIwJTJDJTIyaCUyMiUzQTEwNTUlN0QlMkMlMjJwYWdlJTIyJTNBJTdCJTIydyUyMiUzQTkwMSUyQyUyMmglMjIlM0E5MzQlN0QlMkMlMjJkb2N1bWVudCUyMiUzQSU3QiUyMndpZHRoJTIyJTNBOTAxJTdEJTJDJTIycHJvZHVjdF9ob3N0JTIyJTNBJTIyYnVzaW5lc3Mub2NlYW5lbmdpbmUuY29tJTIyJTJDJTIydmNfdmVyc2lvbiUyMiUzQSUyMjEuMC4wLjYwJTIyJTJDJTIybWFza1RpbWUlMjIlM0ExNzE2MjA5OTc4NDYyJTJDJTIyaDVfY2hlY2tfdmVyc2lvbiUyMiUzQSUyMjQuMC41JTIyJTdEJmFpZD0xNDAyJnNjZW5lX2xldmVsPXAyJmFwcF9uYW1lPWFjd2ViJmhvc3Q9JTJGJTJGdmVyaWZ5LnppamllYXBpLmNvbSZsYW5nPXpoJnRoZW1lPSU3QiUyMmhhbGZfY25fT2tCdG5CZ0NvbG9yJTIyJTNBJTIyJTIzMkE1NUU1JTIyJTdEJnZlcmlmeV9kYXRhPSU3QiUyMmNvZGUlMjIlM0ElMjIxMDAwMCUyMiUyQyUyMmZyb20lMjIlM0ElMjJzaGFya19hZG1pbiUyMiUyQyUyMnR5cGUlMjIlM0ElMjJ2ZXJpZnklMjIlMkMlMjJ2ZXJzaW9uJTIyJTNBJTIyMSUyMiUyQyUyMnJlZ2lvbiUyMiUzQSUyMmNuJTIyJTJDJTIyc3VidHlwZSUyMiUzQSUyMnNsaWRlJTIyJTJDJTIydWlfdHlwZSUyMiUzQSUyMiUyMiUyQyUyMmRldGFpbCUyMiUzQSUyMnhSRnZOOVJhNXE0ZmhHZHc0ek5YdTRsbk5tNmQ0b1dEbW1UU1FPOGxpM1dBOUNEa2JoRUdpaEZqUUFvcEtGY2czVEZHVioqU01ZeFFObWdIN1lHMXZJUnpuM1lORCpOWW14QWFuVmotenprNmNMUFZUWVllS3dicVF0MEpnZlBRRDZ6KnBick9PeGFhS2FPd3ktQnZYczZzcHkqY0lFUU5wQ0c1dGQyd3NXT3FVM21sZ1lJMDlucVhvUDBZRWViRTY4ZW1mVEk1NzkqNW1nTk5hMjdTeHFoeEJBM1AzRHFNb2tDWHRoLVM0SjJMcSpPbHJ5aDg1QTZycFA0TU1SMkg5RmFodTJkUy1oUzNHV254UEdxbGdqZWZlZjljZCpRVE5IckRLd1UxTll5QVUqNS1HVEh0ZEI3aVV6Zk40RU8tVlJzTm1rbWt6YkdpUEFZRXUyMnZ6cGRSVnd2dWhZWWlmeDRqRVhPdDFyY25zVG5mWXNRWmxPYWFCd09XWDh1bEotSDl4TDhjWnpnRTh0enI1dy1XKlc3ZyUyMiUyQyUyMnZlcmlmeV9ldmVudCUyMiUzQSUyMnR0X3Nzb19hY2NvdW50X2xvZ2luJTIyJTJDJTIyZnAlMjIlM0ElMjJ2ZXJpZnlfbHdlejN5ZmdfYmM3YWIxMTRfNGMwOF9lNmU2XzNmZWFfNDc1NzIxM2EwNzE3JTIyJTJDJTIyc2VydmVyX3Nka19lbnYlMjIlM0ElMjIlN0IlNUMlMjJpZGMlNUMlMjIlM0ElNUMlMjJsZiU1QyUyMiUyQyU1QyUyMnJlZ2lvbiU1QyUyMiUzQSU1QyUyMkNOJTVDJTIyJTJDJTVDJTIyc2VydmVyX3R5cGUlNUMlMjIlM0ElNUMlMjJwYXNzcG9ydCU1QyUyMiU3RCUyMiUyQyUyMmxvZ19pZCUyMiUzQSUyMjIwMjQwNTIwMjA1OTM4RTlGN0U5REJGQ0I3Rjc4OTE5NzclMjIlMkMlMjJpc19hc3Npc3RfbW9iaWxlJTIyJTNBZmFsc2UlMkMlMjJpc19jb21wbGV4X3NtcyUyMiUzQWZhbHNlJTJDJTIyaWRlbnRpdHlfYWN0aW9uJTIyJTNBJTIyJTIyJTJDJTIyaWRlbnRpdHlfc2NlbmUlMjIlM0ElMjIlMjIlMkMlMjJ2ZXJpZnlfc2NlbmUlMjIlM0ElMjJwYXNzcG9ydCUyMiUyQyUyMmxvZ2luX3N0YXR1cyUyMiUzQTAlMkMlMjJhaWQlMjIlM0EwJTJDJTIybWZhX2RlY2lzaW9uJTIyJTNBJTIyJTIyJTdE'url=...with sync_playwright() as p:browser = p.chromium.launch(headless=False, args=['--disable-blink-features=AutomationControlled'])page = browser.new_page()page.goto(url)page.wait_for_timeout(2000)  # 滑块加载太慢了等待5秒防止异常# ddddocr识别slide_img_bytes = get_img_bytes_by_htmltag_selector(page, "img#captcha-verify_img_slide")target_img_bytes = get_img_bytes_by_htmltag_selector(page, "img#captcha_verify_image")x = get_distance_by_ddddocr(slide_img_bytes, target_img_bytes)# 计算实际x轴位置selector = "div.captcha-slider-btn"slide_element = page.wait_for_selector(selector)slide_element_pos = slide_element.bounding_box()width = slide_element_pos['width']height = slide_element_pos['height']x = x / (width / height) # 计算实际位置,x/宽高比# 开始滑动mouse = page.mousemouse.move(slide_element_pos['x'], slide_element_pos['y'])page.wait_for_timeout(200)mouse.down()mouse.move(slide_element_pos['x'] + x, slide_element_pos['y'], steps=random.randint(10, 15))page.wait_for_timeout(200)mouse.up()time.sleep(60)browser.close()

在这里插入图片描述

结束

因为在之前的版本中,某音系滑块的背景图顺序是打乱的,如果你获取到图片需要自己进行裁剪合并完整图像,所以我们上面的代码是使用单独的验证码窗口去进行滑动的,并且获取图片的方式是直接读取元素。

实际上也可以直接在登录页面,读取iframe的对象然后直接滑动,并且新版的图片顺序没有打乱,所以滑块的图片可以使用page.on捕获请求,当链接命中请求图片的接口就处理滑块。

如果文章内容有什么地方不对,欢迎评论或者私信提醒。
如果你有更多的案例也可以私信我添加到文章内容中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/329410.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Arthas,应用诊断利器!【送源码】

Arthas 是一款线上监控诊断产品,通过全局视角实时查看应用 load、内存、gc、线程的状态信息,并能在不修改应用代码的情况下,对业务问题进行诊断,包括查看方法调用的出入参、异常,监测方法执行耗时,类加载信…

C#, PCANBasicd.dll库读写CAN设备数据

PCAN-Basic是一个简单的 PCAN 系统编程接口。 通过 PCAN-Basic Dll,可以将自己的应用程序连接到设备驱动程序和 PCAN 硬件,以与 CAN 总线进行通信。支持C、C++、C#、Delphi、JAVA、VB、Python等语言。 PCAN-Basic库和驱动下载地址 ​ ​https://www.peak-system.com/filead…

O2OA(翱途)开发平台数据统计如何配置?

O2OA提供的数据管理中心,可以让用户通过配置的形式完成对数据的汇总,统计和数据分组展现,查询和搜索数据形成列表数据展现。也支持用户配置独立的数据表来适应特殊的业务的数据存储需求。本文主要介绍如何在O2OA中开发和配置统计。 一、先决…

mysql 多表关联查询性能优化-同一sql不同的执行计划

一、问题背景 相同的sql,不同的日期,执行的时间差异很大,执行计划不一样。执行快时,30ms左右。执行慢时,15s左右。 二、分析结论 1、经过分析,发现不同日期下,sql的执行计划不同,驱…

Qt 科目一考试系统(有源码)

项目源码和资源:科目一考试系统: qt实现科目一考试系统 一.项目概述 该项目是一个基于Qt框架开发的在线考试系统,主要实现了考试题目的随机抽取、考试时间限制、成绩统计等功能。用户可以通过界面操作进行考试,并查看自己的考试成绩。 二.技…

【BSP开发经验】用户态栈回溯技术

前言 在内核中有一个非常好用的函数dump_stack, 该函数在我们调试内核的过程中可以打印出函数调用关系,该函数可以帮助我们进行内核调试,以及让我们了解内核的调用关系。同时当内核发生崩溃的时候就会自己将自己的调用栈输出到串口。 栈回溯非常有利于我…

react 下拉框内容回显

需要实现效果如下 目前效果如下 思路 : 将下拉框选项的value和label一起存储到state中 , 初始化表单数据时 , 将faqType对应的label查找出来并设置到Form.Item中 , 最后修改useEffect 旧代码 //可以拿到faqType为0 但是却没有回显出下拉框的内容 我需要faqType为0 回显出下拉…

【实战教程】使用Spring AOP和自定义注解监控接口调用

一、背景 随着项目的长期运行和迭代,积累的功能日益繁多,但并非所有功能都能得到用户的频繁使用或实际上根本无人问津。 为了提高系统性能和代码质量,我们往往需要对那些不常用的功能进行下线处理。 那么,该下线哪些功能呢&…

QTextEdit 控件上显示信息:

目录 1. 使用 append 方法: 2. 使用 setPlainText 方法 3.例子: 1. 使用 append 方法: 如果你希望在 QTextEdit 控件上追加显示新的信息,可以使用 append 方法。例如,当你想要追加一行新的日志信息: self.text_edit.append(&…

卷积神经网络(CNN)详细介绍及其原理详解

卷积神经网络(Convolutional Neural Networks,简称CNN)是深度学习中非常重要的一类神经网络,主要用于图像识别、图像分类、物体检测等计算机视觉任务。本文将详细介绍卷积神经网络的基本概念、结构组成及其工作原理,并…

leetcode以及牛客网单链表相关的题、移除链表元素、链表的中间节点、合并两个有序链表、反转链表、链表分割、倒数第k个节点等的介绍

文章目录 前言一、移除链表元素二、链表的中间节点三、合并两个有序链表四、反转链表五、链表分割六、倒数第k个节点总结 前言 leetcode以及牛客网单链表相关的题、移除链表元素、链表的中间节点、合并两个有序链表、反转链表、链表分割、倒数第k个节点等的介绍 一、移除链表元…

集群分发脚本xsync

1.环境准备 1.准备三台服务器(我这里使用虚拟机,操作系统 CentOS7 )它们的IP分别为 192.168.188.135、192.168.188.136、192.168.188.137 2.先将三台机器的主机名修改,为每台主机设置hostname(具体名称由自己定义)&am…

https为何安全?

HTTPS(超文本传输安全协议)是一种用于安全通信的网络协议,它在HTTP协议的基础上通过SSL/TLS(安全套接层/传输层安全)协议来加密数据,以保护网络数据的传输安全。 TLS/SSL 基础概念 概念源自百度百科&…

电磁兼容(EMC):时钟电路PCB设计

目录 1. 布局 2. 布线 时钟电路做为产品内部的强辐射源,在设计阶段已经选用展频或者分频方案后,见另外接下来就需要对PCB的耦合路径进行规划设计。时钟电路具体的PCB设计具体要求如下: 1. 布局 结构干涉:时钟电路的晶振和法拉电…

BUUCTF---misc---我吃三明治

1、下载附件是一张图片 2、在winhex分析,看到一串整齐的编码有点可疑,保存下来,拿去解码,发现解不了,看来思路不对 3、再仔细往下看的时候也发现了一处这样的编码,但是这次编码后面多了一段base编码 4、拿去…

JS对象超细

目录 一、对象是什么 1.对象声明语法 2.对象有属性和方法组成 二、对象的使用 1.对象的使用 (1)查 (2)改 (3)增 (4)删(了解) (5&#xf…

Linux文件:缓冲区、缓冲区刷新机制 | C库模拟实现

Linux文件:缓冲区、缓冲区刷新机制 | C库模拟实现 一、缓冲区的作用二、缓冲区的刷新机制三、测试样例解析3.1 测试样例和运行结果3.2 结果分析1、向显示器文件写入:2、向磁盘文件进行写入: 四、语言级别的缓冲区究竟在哪?五、C库…

网络原理3

运营商路由器,也可以把它当做一个NAT设备它就会对中间经过的数据包,进行网络地址转换当内网设备经过运营商路由器访问外网的时候就会把IP数据包中的源ip,替换成它自己的ip. 我的电脑要发送一个数据给cctalk服务器此时,我的电脑上就…

二叉树求解大小操作详解

目录 一、求所有结点个数 1.1 递归思路 1.2 递归分支图 1.3 递归栈帧图 1.4 C语言实现 二、求叶子结点个数 2.1 递归思路 2.2 递归分支图 2.3 递归栈帧图 2.4 C语言实现 三、求第K层的结点个数 3.1 递归思路 3.2 递归分支图 3.3 递归栈帧图 3.4 C语言实现 四、求…

高性能负载均衡的分类及架构分析

如何选择与部署适合的高性能负载均衡方案? 当单服务器性能无法满足需求,高性能集群便成为提升系统处理能力的关键。其核心在于通过增加服务器数量,强化整体计算能力。而集群设计的挑战在于任务分配,因为无论在哪台服务器上执行&am…