Python爬虫第22节- 结合Selenium识别滑动验证码实战
目录
一、引言
二、滑动验证码原理与反爬机制
2.1 验证码原理
2.2 反爬机制
三、工程实战:滑动验证码识别全流程
3.1 工程准备
3.1.1 环境依赖
3.1.2 目标网站与验证码识别案例
3.2 核心破解流程
3.2.1 自动化打开网页与登录
3.2.2 获取验证码图片(适配缩放)
3.2.3 识别缺口左边缘
3.2.4 计算滑动距离(左边缘对齐)
3.2.5 生成自然滑动轨迹与回弹
3.2.6 按轨迹移动滑块
3.2.7 主流程整合
结语
🎬 攻城狮7号:个人主页
🔥 个人专栏: 《python爬虫教程》
⛺️ 君子慎独!
🌈 大家好,欢迎来访我的博客!
⛳️ 此篇文章主要介绍 滑动验证码 的识别
📚 本期文章收录在《python爬虫教程》,大家有兴趣可以自行查看!
⛺️ 欢迎各位 ✔️ 点赞 👍 收藏 ⭐留言 📝!
一、引言
随着互联网安全需求的提升,滑动验证码(Slider Captcha)已成为各大网站防止自动化攻击和恶意爬虫的主流手段之一。相比传统的字符型验证码,滑动验证码通过人机交互和行为轨迹分析,大幅提升了破解难度。对于自动化测试、数据采集和安全研究者来说,如何精准识别和模拟滑动验证码,是一项极具挑战性的工程任务。
本章将以实际工程代码为主线,系统讲解结合Selenium知识进行滑动验证码的识别与破解流程(不懂Selenium的请自行学习前面章节),涵盖原理分析、反爬机制、核心代码实现、调试技巧、常见问题与工程实战经验,帮助读者掌握滑动验证码自动化识别的全流程。
二、滑动验证码原理与反爬机制
2.1 验证码原理
滑动验证码的基本流程是:
(1)用户在页面上看到一张带有缺口的图片和一个可拖动的滑块。
(2)用户需要按住滑块,将其拖动到缺口处,使图片拼合完整。
(3)系统通过前端和后端双重校验,判断滑块是否准确对齐缺口,并分析拖动轨迹是否自然。
滑动验证码的常见类型有:
- 拼图型滑动验证码:最常见,用户需将滑块拖到缺口处。
- 轨迹型滑动验证码:要求用户沿特定轨迹拖动滑块。
- 多步验证型:滑动后还需输入字符或完成其他操作。
2.2 反爬机制
滑动验证码的反爬机制主要包括:
- 轨迹分析:检测滑块移动轨迹是否自然(加速度、抖动、停顿等)。
- 环境检测:检测浏览器指纹、User-Agent、Cookie、Referer 等参数。
- 图片混淆:验证码图片可能经过切片、加密、canvas 绘制等处理。
- 行为识别:分析鼠标事件、点击频率、页面交互等行为特征。
破解滑动验证码的难点在于:
- 缺口识别:需精准定位缺口左边缘,避免阴影、边框等干扰。
- 轨迹模拟:需生成近似人类的加速-减速轨迹,并加入微小抖动和回弹。
- 环境伪装:需伪装浏览器指纹、请求头等,防止被反爬机制识别。
三、工程实战:滑动验证码识别全流程
接下来详细讲解滑动验证码识别与破解的完整工程流程。
3.1 工程准备
3.1.1 环境依赖
- Python 3.x
- Selenium
- Pillow (PIL)
- Chrome 浏览器及 ChromeDriver
安装依赖:
pip install selenium pillow
3.1.2 目标网站与验证码识别案例
以保险公司产品查询系统( 财产保险公司自主注册产品查询V1.0.0 )为例,登录页面集成了典型的拼图型滑动验证码。验证码区域如图所示:
下面是实现滑动验证码识别的动图(滑动的速度可以自行调整):
那么我们是如何实现的呢,那请看下面内容分析
3.2 核心破解流程
3.2.1 自动化打开网页与登录
首先,使用 Selenium 自动化打开目标网页,随便输入用户名和密码,点击登录按钮,触发滑动验证码弹窗。下面是定位用户名密码框输入模拟登录操作
from selenium import webdriver # 导入Selenium库,用于自动化浏览器操作from selenium.webdriver.common.by import By # 用于元素定位from selenium.webdriver.support.ui import WebDriverWait # 显式等待,确保元素加载完成from selenium.webdriver.support import expected_conditions as EC # 等待条件from selenium.webdriver import ActionChains # 用于模拟鼠标拖动等复杂操作from PIL import Image, ImageDraw # 图像处理库,用于截图和画辅助线import time # 时间控制class CrackSlider():def __init__(self):self.url = "https://cxcx.iachina.cn/" # 目标网站self.chrome_options = webdriver.ChromeOptions() # 创建Chrome配置对象self.chrome_options.add_experimental_option('excludeSwitches', ['enable-automation']) # 隐藏自动化标识,降低被检测风险self.browser = webdriver.Chrome(options=self.chrome_options) # 启动Chrome浏览器self.browser.maximize_window() # 最大化窗口,防止截图区域不全self.wait = 2 # 默认等待时间(秒)def open(self):self.browser.get(self.url) # 打开目标网页time.sleep(self.wait) # 等待页面加载def input_login_info(self):myname = self.browser.find_element(By.XPATH, "/html/body/form/div/div[2]/div[1]/input[1]") # 定位用户名输入框myname.send_keys("1111") # 输入用户名mycode = self.browser.find_element(By.XPATH, '//*[@id="passWord"]') # 定位密码输入框mycode.send_keys("1111") # 输入密码time.sleep(2) # 等待输入完成def click_login(self):button = self.browser.find_element(By.XPATH, '/html/body/form/div/div[3]/input[5]') # 定位登录按钮button.click() # 点击登录time.sleep(2) # 等待滑动验证码弹出
实现思路与设计原因:
- 采用Selenium自动化浏览器,能够真实模拟用户操作,绕过大部分前端反爬机制。
- 显式等待和sleep结合,确保页面元素加载和渲染完成,避免截图黑屏或元素未找到。
- 最大化窗口和隐藏自动化标识,有助于提升截图准确性和通过率。
3.2.2 获取验证码图片(适配缩放)
验证码图片通常经过缩放或高分屏渲染,需获取 devicePixelRatio 并裁剪出验证码区域。
screenshot_all.png
def get_captcha_image(self, filename):wait = WebDriverWait(self.browser, 10) # 显式等待,确保验证码图片元素可见element = wait.until(EC.visibility_of_element_located((By.XPATH, '//*[@id="slideBar"]/div/div[1]/div[2]/div[2]/div[1]')))time.sleep(2) # 等待图片渲染,防止截图为黑色self.device_pixel_ratio = self.browser.execute_script('return window.devicePixelRatio') # 获取浏览器缩放比例location = element.location # 获取验证码图片左上角坐标(页面坐标)size = element.size # 获取验证码图片宽高left = location['x'] * self.device_pixel_ratio # 左坐标(页面坐标*缩放)top = location['y'] * self.device_pixel_ratio # 上坐标right = left + size['width'] * self.device_pixel_ratio # 右坐标bottom = top + size['height'] * self.device_pixel_ratio # 下坐标self.browser.save_screenshot("screenshot_all.png") # 截取全屏im = Image.open("screenshot_all.png") # 打开截图img = im.crop((left, top, right, bottom)) # 裁剪验证码区域img.save(filename) # 保存验证码图片return img # 返回PIL.Image对象
实现思路与设计原因:
- 通过显式等待和sleep,确保验证码图片已完全渲染,避免截图黑屏。
- 获取devicePixelRatio,适配高分屏和浏览器缩放,保证裁剪区域与实际验证码一致。
- 先全屏截图再裁剪,兼容所有浏览器和页面布局。
3.2.3 识别缺口左边缘
通过对比"无缺口"和"有缺口"两张图片,遍历像素,找出差异最大的区域,确定缺口左边缘。
def get_gap(self, image1, image2):beforecode = image1.convert("L") # 转为灰度图,简化像素对比aftercode = image2.convert("L") # 转为灰度图threshold = 60 # 像素差阈值,调节灵敏度width = beforecode.size[0] # 图片宽度height = beforecode.size[1] # 图片高度diff_w = [] # 存储所有差异点的横坐标for h in range(0, height): # 遍历每一行for w in range(int(round(width/3,0)), width): # 从1/3宽度开始,避开左侧干扰beforepixel = beforecode.getpixel((w,h)) # 获取无缺口像素afterpixel = aftercode.getpixel((w,h)) # 获取有缺口像素if abs(beforepixel - afterpixel) > threshold: # 差异大于阈值diff_w.append(w) # 记录差异点横坐标if diff_w:gap_left = min(diff_w) # 差异区间左边界gap_right = max(diff_w) # 差异区间右边界gap_center = (gap_left + gap_right) // 2 # 取中心点return gap_left, gap_center # 返回左边缘和中心return 0, 0 # 未找到则返回0
实现思路与设计原因:
- 灰度化处理简化像素对比,提升识别速度和鲁棒性。
- 只遍历右侧2/3区域,避开左侧logo或干扰元素。
- 统计所有差异点,取最左为gap_left,最右为gap_right,中心为gap_center。
- 返回gap_left用于滑块左边缘对齐,gap_center用于调试和可视化。
3.2.4 计算滑动距离(左边缘对齐)
滑块左边缘应对齐缺口左边缘,滑动距离为:
gap_left, gap_center = self.get_gap(image1, image2) # 获取缺口左边缘和中心captcha_left = captcha_element.location['x'] * self.device_pixel_ratio # 验证码图片左上角页面坐标gap_left_page = captcha_left + gap_left # 缺口左边缘页面坐标slider_left = slider_location['x'] * self.device_pixel_ratio # 滑块左边缘页面坐标move_distance = gap_left_page - slider_left # 实际需要滑动的距离
实现思路与设计原因:
- 所有坐标都统一为页面坐标并乘以devicePixelRatio,避免缩放误差。
- 滑块左边缘对齐缺口左边缘,符合大多数滑动验证码的判定逻辑。
- move_distance为正,表示向右滑动。
3.2.5 生成自然滑动轨迹与回弹
轨迹需模拟人类加速-减速运动,并在末尾加入回弹和微小抖动。
def get_track(self, distance):if distance <= 0:return [0] # 距离为0直接返回track = [] # 存储每次移动的距离current = 0 # 当前位移mid = distance * 4 / 5 # 前4/5为加速,后1/5为减速t = 0.2 # 时间间隔v = 0 # 初速度while current < distance: # 未到目标距离if current < mid:a = 2 # 加速阶段else:a = -3 # 减速阶段v0 = v # 初速度v = v0 + a * t # 当前速度move = v0 * t + 1 / 2 * a * t * t # 位移current += move # 累加位移track.append(round(move)) # 记录本次移动if len(track) > 0:track[-1] = int(round(distance - sum(track[:-1]))) # 修正最后一步if abs(sum(track) - distance) > 1:track.append(int(distance - sum(track))) # 再次修正return track
实现思路与设计原因:
- 轨迹分为加速和减速两段,模拟人手自然运动。
- 每步位移用物理公式计算,提升轨迹真实性。
- 最后一步修正,确保总距离精确。
- 可在轨迹末尾加微小抖动和回弹,进一步提升"人味"。
轨迹末尾加回弹:
track = self.get_track(move_distance) # 生成主轨迹
track.extend([3, -2, 1, -1]) # 加入回弹和微调
3.2.6 按轨迹移动滑块
def move_to_gap(self, slider, tracks):actions = ActionChains(self.browser) # 创建动作链actions.click_and_hold(slider).perform() # 按住滑块for x in tracks:actions.move_by_offset(xoffset=x, yoffset=0).perform() # 拖动滑块time.sleep(1) # 停顿,模拟人类松手前的停留actions.release().perform() # 松开滑块,完成验证
实现思路与设计原因:
- 使用ActionChains模拟鼠标按住、拖动、松开全过程。
- 每步移动后立即执行,模拟真实鼠标拖动。
- 松手前适当停顿,提升通过率。
3.2.7 主流程整合
beforecode.png(获取的无缺口图片)
aftercode.png(获取的缺口图片)
def crack(self):self.open() # 打开网页self.input_login_info() # 输入用户名和密码self.click_login() # 点击登录,弹出验证码image1 = self.get_captcha_image('beforecode.png') # 获取无缺口图片slider = self.get_slider() # 获取滑块元素slider.click() # 点击滑块,显示缺口time.sleep(3) # 等待缺口图片渲染image2 = self.get_captcha_image('aftercode.png') # 获取带缺口图片gap_left, gap_center = self.get_gap(image1, image2) # 识别缺口左边缘和中心captcha_element = self.browser.find_element(By.XPATH, '//*[@id="slideBar"]/div/div[1]/div[2]/div[2]/div[1]') # 验证码元素captcha_left = captcha_element.location['x'] * self.device_pixel_ratio # 验证码左上角页面坐标gap_left_page = captcha_left + gap_left # 缺口左边缘页面坐标slider_location = slider.location # 滑块左上角页面坐标slider_size = slider.size # 滑块宽高slider_left = slider_location['x'] * self.device_pixel_ratio # 滑块左边缘页面坐标slider_center = slider_left + slider_size['width'] * self.device_pixel_ratio / 2 # 滑块中心页面坐标move_distance = gap_left_page - slider_left # 需要滑动的距离print(f"gap_left (in image): {gap_left}")print(f"gap_center (in image): {gap_center}")print(f"captcha_left (page): {captcha_left}")print(f"gap_left_page: {gap_left_page}")print(f"slider_left: {slider_left}")print(f"slider_center: {slider_center}")print(f"move_distance (left edge align): {move_distance}")img1_debug = image1.copy() # 调试用图片img2_debug = image2.copy()self.draw_debug_line(img1_debug, gap_left, 'green', 'beforecode_debug.png') # 画缺口左边缘self.draw_debug_line(img1_debug, gap_center, 'red', 'beforecode_debug.png') # 画缺口中心self.draw_debug_line(img2_debug, gap_left, 'green', 'aftercode_debug.png')self.draw_debug_line(img2_debug, gap_center, 'red', 'aftercode_debug.png')slider_center_in_img = int(slider_center - captcha_left) # 滑块中心在图片内的横坐标self.draw_debug_line(img1_debug, slider_center_in_img, 'blue', 'beforecode_debug.png') # 画滑块中心track = self.get_track(move_distance) # 生成轨迹track.extend([3, -2, 1, -1]) # 加入回弹print(f"track: {track}")print(f"track sum: {sum(track)}")self.move_to_gap(slider, track) # 拖动滑块time.sleep(2) # 等待验证结果self.browser.close() # 关闭浏览器
实现思路与设计原因:
- 主流程串联所有步骤,自动化完成验证码识别与破解。
- 关键变量和调试图片便于排查问题和优化算法。
- 结构清晰,便于扩展和维护。
结语
滑动验证码的自动识别与破解,是自动化测试、数据采集和安全攻防领域的经典难题。本文以实际工程代码为主线,系统梳理了滑动验证码的原理、反爬机制、识别与破解流程、核心算法实现、调试技巧与工程经验。通过对缺口识别、轨迹生成、滑块模拟等关键环节的逐步剖析,我们不仅掌握了破解滑动验证码的技术细节,也深入理解了背后的安全逻辑与攻防博弈。
在实际工程中,滑动验证码的样式和反爬机制会不断演化,破解方法也需灵活调整。面对更复杂的验证码(如canvas绘制、AI行为识别、图片加密等),我们可以结合深度学习、图像处理、浏览器指纹伪装等多种手段,不断提升自动化能力。
滑动验证码的研究,不仅有助于提升自动化测试和数据采集的效率,更有助于理解Web安全、反爬机制和人机交互的前沿发展。希望本章内容能为你的工程实践和技术探索提供有力参考。未来,随着AI与安全技术的持续进步,滑动验证码的攻防也将更加精彩,期待你在实践中不断创新、持续精进!
看到这里了还不给博主点一个:
⛳️ 点赞
☀️收藏
⭐️ 关注
!
💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
再次感谢大家的支持!
你们的点赞就是博主更新最大的动力!
相关文章:

Python爬虫第22节- 结合Selenium识别滑动验证码实战
目录 一、引言 二、滑动验证码原理与反爬机制 2.1 验证码原理 2.2 反爬机制 三、工程实战:滑动验证码识别全流程 3.1 工程准备 3.1.1 环境依赖 3.1.2 目标网站与验证码识别案例 3.2 核心破解流程 3.2.1 自动化打开网页与登录 3.2.2 获取验证码图片&#…...
【C/C++】chrono简单使用场景
chrono使用场景举例 1 输出格式化字符串 示例代码 auto now std::chrono::system_clock::now(); auto t std::chrono::system_clock::to_time_t(now); auto ms std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000;std::ostrin…...

Escrcpy(安卓手机投屏软件) v1.29.6 中文绿色版
在数字设备日益普及的今天,用户对于设备的控制和管理需求也在不断增加。对于Android设备用户来说,Escrcpy这款强大的工具无疑是一个福音。它不仅提供了直观的图形化界面,让用户能够轻松显示和控制自己的Android设备,还以完全免费开…...
Oracle MOVE ONLINE 实现原理
Oracle MOVE ONLINE 实现原理 Oracle 的 MOVE ONLINE 操作是一种在线重组表的技术,允许在不中断业务的情况下重新组织表数据。以下是其实现原理的详细分析: 基本概念 MOVE ONLINE 是 Oracle 12c 引入的特性,用于替代传统的 ALTER TABLE ..…...

Linux:深入理解网络层
网络层在复杂的网络环境中确定一个合适的路径.传输到指定的网络中 一、网络层的理解 问题1:为什么要有网络层的概念呢?? ——>我们先来讲一个故事: 假设我在学校里被誉为数学大神,是因为我的数学有考满分的能力&…...
【设计模式】简单工厂模式,工厂模式,抽象工厂模式,单例,代理,go案例区分总结
工厂模式三种类型: 一、简单工厂模式(Simple Factory) 定义: 用一个工厂类,根据传入的参数决定创建哪一种具体产品类实例。 面试说法: 由一个统一的工厂创建所有对象,增加新产品时需要修改工…...

Linux_编辑器Vim基本使用
✨✨ 欢迎大家来到小伞的大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:LInux_st 小伞的主页:xiaosan_blog 制作不易!点个赞吧!!谢谢喵!&a…...

vue展示修改前后对比,并显示修改标注diff
动态父组件 <template><el-buttontype"primary"size"small"plainclick"showDiffDialog(subItem)">查看修改内容</el-button><TextDiffDialogv-model:visible"diffDialogVisible":before"currentDiffItem?.…...

LiveWallpaperMacOS:让你的 Mac 桌面动起来
随着桌面美化需求的不断提升,用户对于桌面壁纸的要求已经不再局限于静态图片。越来越多的 Mac 用户希望桌面能像 Windows 一样,拥有动态壁纸,展现个性、提升体验。LiveWallpaperMacOS 正是这样一款让你的 Mac 桌面焕发活力的开源项目。 本文将详细介绍 LiveWallpaperMacOS …...
[预训练]Encoder-only架构的预训练任务核心机制
原创文章1FFN前馈网络与激活函数技术解析:Transformer模型中的关键模块2Transformer掩码技术全解析:分类、原理与应用场景3【大模型技术】Attention注意力机制详解一4Transformer核心技术解析LCPO方法:精准控制推理长度的新突破5Transformer模…...

07-后端Web实战(部门管理)
5. 修改部门 对于任何业务的修改功能来说,一般都会分为两步进行:查询回显、修改数据。 5.1 查询回显 5.1.1 需求 当我们点击 "编辑" 的时候,需要根据ID查询部门数据,然后用于页面回显展示。 5.1.2 接口描述 参照参照…...

mysql ACID 原理
序言:ACID 是一组数据库设计原则,他是业务数据和关键业务程序的可靠性保障。 1、atomicity(原子性) 依赖如下能力 autocommit commit rollback2、一致性 2.1 double write buffer 1、定义:double write buffer 是…...

[Rust_1] 环境配置 | vs golang | 程序运行 | 包管理
目录 Rust 环境安装 GoLang和Rust 关于Go 关于Rust Rust vs. Go,优缺点 GoLang的优点 GoLang的缺点 Rust的优点 Rust的缺点 数据告诉我们什么? Rust和Go的主要区别 (1) 性能 (2) 并发性 (3) 内存安全性 (4) 开发速度 (5) 开发者体验 Ru…...

二十五、面向对象底层逻辑-SpringMVC九大组件之HandlerMapping接口设计
一、引言:MVC架构的交通枢纽 在Spring MVC框架中,HandlerMapping接口扮演着"请求导航仪"的关键角色,它决定了HTTP请求如何被路由到对应的Controller处理器。作为MVC模式的核心组件之一,HandlerMapping在请求处理的生命…...
构建安全高效的邮件网关ngx_mail_ssl_module
一、快速上手:最小配置示例 worker_processes auto;mail {server {# 监听 IMAP over TLSlisten 993 ssl;protocol imap;# TLS 协议与密码套件ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers HIGH:!aNULL:!MD5;# 证书与私钥ssl_…...

HUAWEI交换机配置镜像口验证(eNSP)
技术术语: 流量观察口:就是我们常说的镜像口,被观察的流量的引流目的端口 流量源端口:企业生产端口,作为观察口观察对象。 命令介绍: [核心交换机]observe-port [观察端口ID或编号(数字&am…...

前端vue3实现图片懒加载
场景和指令用法 场景:电商网站的首页通常会很长,用户不一定能访问到页面靠下面的图片,这类图片通过懒加载优化手段可以做到只有进入视口区域才发送图片请求 核心原理:图片进入视口才发送资源请求 首先:我们需要定义一个全局的指令&#x…...
网站每天几点更新,更新频率是否影响网站收录
1. 每天几点更新网站最合适?总怕时间选错影响收录? 刚开始搞网站的时候,是不是老纠结啥时候更新合适?早上刚上班?半夜没人的时候?选不对时间,总担心搜索引擎爬虫来了没抓到新内容,影…...
主流Markdown编辑器的综合评测与推荐
根据2025年最新资料,结合功能特性、用户体验和技术适配性,以下是对主流Markdown编辑器的综合评测与推荐: 一、核心对比维度与评估方法 功能完整性:支持数学公式、流程图、代码高亮等复杂格式。跨平台兼容性:Windows/m…...

计算机网络-MPLS VPN应用场景与组网
上一篇文章我们通过一个基础实验实现了企业分支间的MPLS VPN互联,如果还不理解的可以多看几遍前面的文章或者多敲下实验。今天来学习几种常见的MPLS VPN应用场景与这些场景下MPLS VPN的部署方法。 一、MPLS VPN典型应用 目前,MPLS VPN的主要应用包括企…...
AugmentFree:解除 AugmentCode 限制的终极方案 如何快速清理vscode和AugmentCode缓存—windows端
AugmentFree1.0工具包:解除 AugmentCode 免费试用限制的终极方案 Augment VIP 是一个专为 VS Code 用户设计的实用工具包,旨在帮助用户管理和清理 VS Code 数据库,解除 AugmentCode 免费试用账户的限制。 augment从根源上解决免费额度限制问…...
WPF【11_7】WPF实战-重构与美化(ViewModel的嵌套与分解、海量数据不要Join)
11-12 【重构】ViewModel的嵌套与分解 目前我们的代码中有一个不易发现的致命问题,如果工作中这样写代码大概率会被打回去重做。那么这个问题是什么呢? --\ViewModels\MainViewModel.cs 视图模型中的 LoadCustomers() 方法,考虑一下在这里我…...

Linux 的编辑器--vim
1.Linux编辑器-vim使⽤ vi/vim的区别简单点来说,它们都是多模式编辑器,不同的是vim是vi的升级版本,它不仅兼容vi的所有指令,⽽且还有⼀些新的特性在⾥⾯。例如语法加亮,可视化操作不仅可以在终端运⾏,也可以…...
Oracle 慢sql排查
Oracle慢sql排查步骤 1.1. 前言 Oracle 慢查询的排查方向包括以下几个方向 : 基准测试 (吞吐量): 包括 Oracle 本身吞吐量和磁盘 I/O 吞吐量硬件分析 (资源情况): 包括查看服务器 CPU , 硬盘的使用情况SQL分析:分析 SQL 中是否存在慢查询 , 是否命中索引配置优化…...

[Protobuf] 快速上手:安全高效的序列化指南
标题:[Protobuf] (1)快速上手 水墨不写bug 文章目录 一、什么是protobuf?二、protobuf的特点三、使用protobuf的过程?1、定义消息格式(.proto文件)(1)指定语法版本(2)package 声明符 2、使用protoc编译器生成代码&…...
uniapp开发企业微信小程序时 wx.qy.login 在uniapp中使用的时候,需要导包吗?
在 UniApp 中使用 “wx.qy.login” 不需要手动导包,但需要满足以下条件: 一、环境要求与配置 1� 企业微信环境判断 必须确保当前运行环境是企业微信客户端,通过 “uni.getSystemInfoSync().environment” 判断是否为 “wxwork”…...

如何将通话记录从Android传输到Android
“如何将通话记录从 Android 转移到 Android?我换了一部新的 Android 手机,想要将通话记录复制到其中。”您需要将通话记录从 Android 传输到 Android 是一种常见的情况,因为通话记录是手机上最重要的数据之一。幸运的是,如果您从…...
Word 目录自动换行后错位与页码对齐问题解决教程
📘 Word 目录自动换行错位与页码对齐问题解决教程 🎯 目标效果 目录条目过长自动换行后,第二行左对齐整齐;页码始终靠右对齐,前方带有“……”引导符;解决页码错位、制表符消失或格式混乱问题。 …...

数据结构第4章 栈、队列和数组 (竟成)
目录 第 4 章 栈、队列和数组 4.1 栈 4.1.1 栈的基本概念 4.1.2 栈的基本操作 4.1.3 栈的实现 1.顺序栈 2.链式栈 3.共享栈 4.1.4 顺序栈的基本操作实现 1.初始化栈 2.判空 3.判满 4.元素进栈 5.元素出栈 6.获取栈顶元素 4.1.5 链栈的基本操作实现 1.元素进栈 2.元素出栈 4.1.6…...
removeIf() 方法,结合 Lambda 表达式
在 Java 8 中,removeIf() 方法是 Collection 接口新增的一个默认方法,用于根据条件批量删除集合中的元素。结合 Lambda 表达式,可以以极简的语法实现复杂的过滤逻辑。以下是详细说明: 1. 方法定义与语法 // java.util.Collection 接口中的定义 default boolean removeIf(P…...