python实现验证码自动化浏览器操作和图像处理
引言
在现代Web开发和自动化测试中,使用编程语言来模拟人类行为进行网页浏览、数据抓取或执行特定任务变得越来越普遍。本文将介绍如何利用Python结合DrissionPage
库和OpenCV
库来实现一个自动化的浏览器操作脚本,该脚本能够登录到指定的网站,并通过图像处理技术解决滑动验证码问题。
环境准备
首先,确保安装了必要的Python库。可以通过pip命令安装DrissionPage、opencv-python等依赖项:
代码解析
引入必要的模块
ChromiumPage
和ChromiumOptions
用于配置和启动基于Chromium内核的浏览器实例。Actions
提供了一套API来模拟用户交互,如鼠标移动、点击等。DownloadKit
用来下载网络资源,例如图片。cv2
是OpenCV库的别名,提供了一系列图像处理功能。浏览器设置
创建了一个
ChromiumOptions
对象co
,并通过set_argument('--guest')
方法设置了无痕模式,避免对用户的浏览历史造成影响。定义图像处理函数
get_pos
该函数接收一张图片路径作为参数,使用OpenCV读取图片并进行预处理(高斯模糊和边缘检测)。
接着,它寻找符合条件的轮廓(即验证码中的缺口),计算其位置,并返回缺口的x坐标及宽度和高度。
如果找到了匹配的轮廓,还会在原图上绘制红色矩形框标记出来,并保存为新文件。
启动浏览器并访问目标网站
使用
ChromiumPage(co)
创建一个新的浏览器页面对象page
。调用
page.get()
方法打开登录页面。填写登录信息
利用
ele()
方法根据属性值选择输入框,并调用input()
方法输入账号密码。触发验证码
找到验证码按钮并点击以显示验证码。
处理验证码
获取包含验证码的iframe元素,并切换至该iframe上下文。
从验证码图片的样式属性中提取图片URL,使用
DownloadKit
下载图片。调用
get_pos
函数分析图片,确定缺口的位置。模拟拖拽动作
根据计算出的缺口位置调整拖拽距离,并创建一系列动作链来模拟用户拖动滑块的行为。
完成拖拽后,点击登录按钮提交表单。
代码如下
from DrissionPage import ChromiumPage,ChromiumOptions from DrissionPage.common import Actions from DownloadKit import DownloadKit import cv2 # opencv库 import time import re # 浏览器设置 co = ChromiumOptions() co.set_argument('--guest') # 封装的计算图片距离的算法 def get_pos(imageSrc): # 读取图像文件并返回一个image数组表示的图像对象 image = cv2.imread(imageSrc) # GaussianBlur方法进行图像模糊化/降噪操作。 # 它基于高斯函数(也称为正态分布)创建一个卷积核(或称为滤波器),该卷积核应用于图像上的每个像素点。 blurred = cv2.GaussianBlur(image, (5, 5), 0, 0) # Canny方法进行图像边缘检测 # image: 输入的单通道灰度图像。 # threshold1: 第一个阈值,用于边缘链接。一般设置为较小的值。 # threshold2: 第二个阈值,用于边缘链接和强边缘的筛选。一般设置为较大的值 canny = cv2.Canny(blurred, 0, 100) # 轮廓 # findContours方法用于检测图像中的轮廓,并返回一个包含所有检测到轮廓的列表。 # contours(可选): 输出的轮廓列表。每个轮廓都表示为一个点集。 # hierarchy(可选): 输出的轮廓层次结构信息。它描述了轮廓之间的关系,例如父子关系等。 contours, hierarchy = cv2.findContours(canny, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 遍历检测到的所有轮廓的列表 for contour in contours: # contourArea方法用于计算轮廓的面积 area = cv2.contourArea(contour) # arcLength方法用于计算轮廓的周长或弧长 length = cv2.arcLength(contour, True) # 如果检测区域面积在5025-7225之间,周长在300-380之间,则是目标区域 if 5025 < area < 7225 and 300 < length < 380: # 计算轮廓的边界矩形,得到坐标和宽高 # x, y: 边界矩形左上角点的坐标。 # w, h: 边界矩形的宽度和高度。 x, y, w, h = cv2.boundingRect(contour) print("计算出目标区域的坐标及宽高:", x, y, w, h) # 在目标区域上画一个红框看看效果 cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2) cv2.imwrite("111.jpg", image) return x,w,h return 0 # 启动浏览器 page = ChromiumPage(co) # 打开登录地址 page.get('https://xxx.xxx.com/login') # 输入账号、密码 根据@placeholder定位输入框 page.ele('@placeholder=邮箱或手机号码').input(vals='xxxx@demo.com',clear=True) page.ele('@placeholder=密码').input(vals='123456',clear=True) # 点击验证码按钮,弹出验证码 page.ele('xpath://*[@id="app"]/div/div[1]/div/div[1]/div/div[2]/div/main/form/div[3]/div[1]/div/button').click() time.sleep(1) # 获取验证码iframe iframe = page('#tcaptcha_iframe_dy') iframe = page.get_frame(iframe) # 验证码图片 ele1 = iframe('#slideBg') # 从style中匹配url img_url = ele1.attr('style') urls = re.findall(r'url\("([^"]+)"\)', img_url) # 下载 d = DownloadKit() # 设置下载图片覆盖已有图片 d.set.if_file_exists.overwrite() d(file_url=urls[0],rename='1.jpg') time.sleep(2) # 调用方法获取缺口的x轴 x = get_pos('1.jpg') # 验证码小方块不在顶头,减去60 x = x-60 # 最终移动的距离 newDis = int(x * 340 / 672 ) # 创建动作链滑动鼠标 ac = Actions(iframe) # 滑动的元素、按住鼠标左键、移动(x,y,速度)、松开鼠标左键 ac.move_to('.tc-fg-item tc-slider-normal').hold().move(newDis,0,0.5).release('.tc-fg-item tc-slider-normal') # 点击登录按钮 page.ele('.__button-dark-enagr0-lmmp n-button n-button--primary-type n-button--medium-type n-button--block').click()