巨某量引擎后台登录实战笔记 | 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.mzph.cn/pingmian/13666.shtml

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

相关文章

网络的基础理解

文章目录 网络的基础认识 网络协议协议分层OSI七层模型TCP/IP 五层/四层 模型 网络的基础认识 先来看下面几个问题 什么是网络? 网络就是有许多台设备包括计算机单不仅限于计算机,这些设备通过相互通信所组成起来系统,我们称之为网络所以如…

Gartner发布中国数据安全安全与风险管理领导者指南:将孤立的数据安全产品集成到数据安全平台中,实施一致的数据安全策略

在中国开展业务或与中国相关的组织面临着越来越多的数据安全风险和法规。安全和风险管理领导者必须采用风险优先的数据安全计划和投资,以响应监管要求,以增强数据驱动的数字创新能力。 主要发现 跨组织职能的分散的数据安全举措和不协调的利益相关者责任…

服务器c盘爆满了,这几种方法可以帮助C盘“瘦身”

我们在使用服务器的时候基本不会在C盘安装软件,那么用久了发现C盘满了,提示空间不足?那么这是怎么回事,为什么空间会占用这么快呢? 原因一: C盘满了,很可能是因为电脑里的垃圾文件过多。操作系…

薪资不公、晋升无望?动笔写一份申诉材料吧!

薪资不公、晋升无望?动笔写一份申诉材料吧! 引言:每个努力工作的人都值得公平对待 在职场上,我们付出了汗水和智慧,期待着相应的回报——合理的工资和公正的晋升机会。然而,现实并不总是如此美好。当你感觉…

芯片设计公司外协ERP数字化运营:科技与管理的融合

随着信息技术的快速发展,ERP(企业资源计划)系统已经成为现代企业管理不可或缺的一部分。在芯片设计行业,由于产品的复杂性、技术的高要求以及市场的快速变化,外协ERP数字化运营显得尤为重要。 芯片设计公司的外协ERP数字化运营,主…

xxe漏洞--xml外部实体注入漏洞

1.xxe漏洞介绍 XXE(XML External Entity Injection)是一种攻击技术,它允许攻击者注入恶意的外部实体到XML文档中。如果应用程序处理XML输入时未正确配置,攻击者可以利用这个漏洞访问受影响系统上的敏感文件、执行远程代码、探测内…

晶体振荡器

一、晶振与晶体区别 晶振是有源晶振的简称,又叫振荡器,英文名称是oscillator,内部有时钟电路,只需供电便可产生振荡信号;晶体是无源晶振的简称,也叫谐振器,英文名称是crystal,是无极…

机械臂与Realsense D435 相机的手眼标定ROS包

本教程主要介绍机械臂与 Realsense D435 相机手眼标定的配置及方法。 系统:Ubuntu 20.0.4 ◼ ROS:Noetic ◼ OpenCV 库:OpenCV 4.2.0 ◼ Realsense D435:librealsense sdk(2.50.0)、realsense-ros 功能包&…

Kafka-文件存储机制

Kafka概述 Kafka-文件存储机制 1. 分区: Kafka中的每个主题(topic)都可以分成一个或多个分区。 Topic是逻辑上的概念,而Partition是物理上的概念。 分区是消息的基本单元,每个分区都是一个有序的log日志文件。 Pr…

Linux网络配置全攻略:解读/etc/network/interfaces文件的精髓

欢迎来到我的博客,代码的世界里,每一行都是一个故事 Linux网络配置全攻略:解读/etc/network/interfaces文件的精髓 前言文件结构与基本概念配置网络接口的常用参数高级网络配置技巧实用工具与调试技巧实战案例与最佳实践 前言 在我们的日常生…

【数据库基础】基本认识数据库--入门引导

文章目录 什么是数据库?主流数据库基本使用安装MySQL连接服务器服务器、数据库、表关系使用案例数据逻辑存储 MySQL架构SQL语句分类什么叫存储引擎 什么是数据库? 数据库是指在磁盘和内存中存储特定结构组织的数据。数据库通常用于存储于某个系统、组织或…

基于springboot实现的校园博客系统

开发语言:Java 框架:springboot JDK版本:JDK1.8 服务器:tomcat7 数据库:mysql 5.7(一定要5.7版本) 数据库工具:Navicat11 开发软件:eclipse/myeclipse/idea Maven…

Mac SourceTree配置ssh git仓库

一、准备条件 1、Mac系统电脑 2、安装好SourceTree 3、获取ssh git仓库地址 二、配置步骤 1、打开终端命令行 ssh -t rsa -C "xxx""xxx"代表注册git仓库时,使用的用户名,可以是字符串也可以是邮箱地址。 如果遇到输入密码&#xf…

无线网络安全技术基础

无线网络安全技术基础 无线网络安全风险和隐患 随着无线网络技术广泛应用,其安全性越来越引起关注.无线网络的安全主要有访问控制和数据加密,访问控制保证机密数据只能由授权用户访问,而数据加密则要求发送的数据只能被授权用户所接受和使用。 无线网络在数据传输时以微波进…

数据访问层设计_6.连接对象管理设计

1.数据库连接管理 在基于JDBC的数据库应用开发中,数据库连接的管理是一个难点,因为它是决定该应用性能的一个重要因素。 对于共享资源,有一个很著名的设计模式——资源池。该模式正是为了解决资源频繁分配、释放所造成的问题。把该模式应用到…

Centos7.9安装卸载Docker

文章目录 1、官网安装1.1、卸载旧版本Docker1.2、通过rpm仓库安装1.2.1、设置仓库1.2.2、安装Docker Engine1.2.3、启动Docker1.2.4、验证安装 1.3、通过rpm软件包安装1.4、通过便捷脚本安装 2、yum安装2.1、安装docker-ce以及客户端2.2、启动docker2.3、配置镜像加速 3、卸载D…

Linux安装刻录软件

在工作场景经常使用光盘和刻录机,在windows系统下有nero软件,在linux下有k3b,但是原始的k3b只能一次刻录,十分浪费光盘,这里我们使用经优麒麟优化过的刻录软件,实现多次追加刻录。 进入优麒麟软件仓库,需要…

项目管理—需求管理规程(软件研发过程标准,管理标准,标书技术编写,资质评审,安全管理体系,项目交付,实施运维,各类建设方案)

软件资料清单列表部分文档清单:工作安排任务书,可行性分析报告,立项申请审批表,产品需求规格说明书,需求调研计划,用户需求调查单,用户需求说明书,概要设计说明书,技术解…

30.包名的修改和新建后端模块

权限和第三方登录确实令人头疼,我们来学一点简单一点的。 另外,如果各位有属于自己的域名和ICP/IP备案,布置一个作业,自行实现第三方QQ登录。 我们所说的包名修改,是一次性修改ruoyi的全部包名,因为发现很多人有这样的需求,下载别人的代码,想要改成自己公司的包名,结…

Spring Boot:SpringBoot 如何优雅地定制JSON响应数据返回

一、前言 目前微服务项目中RESTful API已经是前后端对接数据格式的标配模式了,RESTful API是一种基于REST(Representational State Transfer,表述性状态转移)原则的应用程序编程接口(Application Programming Interfac…