找回密码
 会员注册
查看: 24|回复: 0

Python从入门到进阶39、使用Selenium自动验证滑块登录

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
71754
发表于 2024-9-6 17:05:22 | 显示全部楼层 |阅读模式
接上篇《38、selenium关于Chromehandless的基本使用》上一篇我们介绍了selenium中有关Chrome的无头版浏览器ChromeHandless的使用。本篇我们使用selenium做一些常见的复杂验证功能,首先我们来讲解如何进行滑块自动验证的操作。一、测试用例介绍我们要通过selenium来实现目前常见的滑块验证码的验证,以豆瓣的登录页面为例:其操作步骤就是:(1)打开登录页面https://accounts.douban.com/passport/login:(2)点击页面上的“密码登录”:(3)输入账号密码之后,点击“登录豆瓣”按钮:(4)拼接好弹出的滑块进行登录验证:二、需要用到的技术1、python语言这里不再赘述,本篇主要还是使用python技术来实现。2、selenium库selenium是一个用于测试Web应用程序的Python库。它可以模拟用户在浏览器中的操作,例如点击、填写表单等。Selenium可以与各种浏览器交互,并提供了丰富的API来控制浏览器行为和获取网页内容。3、urllib库urllib是Python标准库之一,用于处理URL相关的操作。它包含多个子模块,例如urllib.request用于发送HTTP请求并获取响应,urllib.parse用于解析和构建URL,urllib.error用于处理URL相关的错误等。urllib常用于网络数据抓取、访问API等任务。4、cv2库cv2是OpenCV(OpenSourceComputerVision)库的Python绑定。OpenCV是一个广泛使用的计算机视觉库,提供了丰富的图像处理和计算机视觉算法。cv2库为Python开发者提供了对OpenCV功能的访问,可以进行图像加载、处理、分析以及计算机视觉任务,如人脸识别、目标检测等。安装注意事项:如果直接通过pipinstallcv2安装报错的话,请使用下面的语句安装:pipinstallopencv-python5、random库random是Python的随机数生成库。它提供了多种随机数生成函数,包括生成伪随机数的函数和从序列中随机选择元素的函数。random库可用于模拟、游戏开发、密码学等领域,以及各种需要随机性的应用程序。6、re库re是Python的正则表达式模块,用于对字符串进行模式匹配和处理。正则表达式是一种强大的文本匹配工具,可以用来搜索、替换、提取特定模式的字符串。re库提供了函数和方法来编译正则表达式、执行匹配操作,并返回匹配结果,使得处理文本数据更加灵活和高效。三、实现步骤下面我们使用代码来实现滑块的验证。1、打开登录页切换密码登录第一步,打开登录页面,并点击页面上的“密码登录”:代码:importtime #事件库,用于硬性等待fromseleniumimportwebdriver #导入selenium的webdriver模块fromselenium.webdriver.common.byimportBy #引入By类选择器#创建ChromeWebDriver对象driver=webdriver.Chrome()try:  #打开豆瓣登录页  driver.get("https://accounts.douban.com/passport/login")  print(driver.title) #打印页面的  #(1)获取“密码登录”选项元素,并点击它  #使用浏览器的F12开发者工具,使用copyxpath获取该元素的XPATH路径  passClick=driver.find_element(By.XPATH,'//*[@id="account"]/div[2]/div[2]/div/div[1]/ul[1]/li[2]')  passClick.click()  #整体等待5秒看结果  time.sleep(5)finally:  #关闭浏览器  driver.quit()效果:值得注意的是,这里的“密码登录”的CSS选择器路径,是通过浏览器F12打开开发者选项,使用“copyxpath”功能复制的。效果:2、输账密点击登录第二步,输入账号密码,并点击“登录豆瓣”按钮:#使用浏览器隐式等待3秒driver.implicitly_wait(3)#获取账号密码组件并赋值userInput=driver.find_element(By.ID,"username")userInput.send_keys("jackzhucoder@126.com")passInput=driver.find_element(By.ID,"password")passInput.send_keys("123456")#获取登录按钮并点击登录loginButton=driver.find_element(By.XPATH,'//*[@id="account"]/div[2]/div[2]/div/div[2]/div[1]/div[4]/a')loginButton.click()这里的登录按钮的xpath路径,也是使用开发者选项的“copyxpath”功能复制。效果:3、切换焦点并下载验证图片将焦点切换至滑块验证区域,并下载加载好的滑块验证背景图片。点击登录按钮后,就会出现滑块验证区域,这是一个新增的frame区域,此时我们需要将切换的焦点从主页面转换到这个frame区域上:代码上我们使用WebDriver的switch_to.frame方法即可,参数就是frame区域的id名“tcaptcha_iframe_dy”。然后我们需要获取整个需要对其的大图片,获取其路径并下载到本地,准备进行读取验证:这里图片元素获取比较简单,通过ID名“slideBg”获取即可,但是图片路径需要分析其style属性中的css参数,通过正则表达式将图片src地址解析出来,然后通过urllib访问这个路径将图片下载下来。解析图片前,一定一定要等待图片元素加载完成之后再获取,否则会什么也解析不到。代码:driver.implicitly_wait(5) #使用浏览器隐式等待5秒#此时需要切换到弹出的滑块区域,需要切换frame窗口driver.switch_to.frame("tcaptcha_iframe_dy")#等待滑块验证图片加载后,再做后面的操作WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,'slideBg')))#获取滑块验证图片下载路径,并下载到本地bigImage=driver.find_element(By.ID,"slideBg")s=bigImage.get_attribute("style") #获取图片的style属性#设置能匹配出图片路径的正则表达式p='background-image:url\(\"(.*?)\"\);'#进行正则表达式匹配,找出匹配的字符串并截取出来bigImageSrc=re.findall(p,s,re.S)[0] #re.S表示点号匹配任意字符,包括换行符print("滑块验证图片下载路径:",bigImageSrc)#下载图片至本地urllib.request.urlretrieve(bigImageSrc,'bigImage.png')下载图片的效果:4、拖动滑块至缺口处我们接下来要做的,是将小拼图图片,移动到缺口处:我们需要获取小图片到缺口处的实际距离,一般用到两种方法。第一种方法是模板匹配,通过openCV分析两个图片的相似度,获取两个相似度很高图片的坐标,从而计算两个图片的距离。第二种方法是轮廓检测,通过openCV进行轮廓检测,即在大图片中找到缺口位置的坐标,然后计算小图片到缺口位置的距离。这里因为我们无法单独获取小拼图的单独图片,所以不好使用模板匹配的方法,所以我们选择使用第二种轮廓检测的方法。(1)得到缺口轮廓位置信息首先我们计算一下缺口的坐标及面积大概有多大,使用PhotoShop打开下载的图片,单独将缺口按照正方形的尺寸抠出来,发现其长宽各是80像素:所以这个封闭矩形的面积范围大概是在80*80=6400像素左右。周长是80*4=320像素。但是现实中这里是有缺口的,不是一个完整的图片,所以我们需要给它一定的误差范围,这里我们暂定目标区域面积为5025-7225,周长为300-380。然后我们将计算距离的逻辑封装为一个方法:#封装的计算图片距离的算法defget_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)  #遍历检测到的所有轮廓的列表  forcontourincontours:    #contourArea方法用于计算轮廓的面积    area=cv2.contourArea(contour)    #arcLength方法用于计算轮廓的周长或弧长    length=cv2.arcLength(contour,True)    #如果检测区域面积在5025-7225之间,周长在300-380之间,则是目标区域    if5025
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-10 13:17 , Processed in 0.536640 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表