1. 介绍
现在的网站大多都采用了滑动验证技术来防止机器人进行恶意登录,而在爬虫或自动化测试的时候,这种技术就会给我们带来困扰。本文将介绍如何利用python、opencv和selenium自动化登录邮箱并解决滑动验证的问题。
2. 环境准备
2.1 Python环境安装
如果您还没有Python环境,请前往Python官网下载安装。
2.2 OpenCV安装
OpenCV是一个广泛用于计算机视觉和机器学习领域的开源计算机视觉库,可以用于图像处理和计算机视觉方面的很多任务。
要安装OpenCV,请执行以下命令:
pip install opencv-python-headless
在安装过程中,可能会从互联网自动下载依赖包并安装。
2.3 Selenium安装
Selenium是一个用于Web应用程序自动化测试的库,通过模拟用户交互来测试Web应用程序。
Selenium可以在多个浏览器中运行,并提供了逼真的用户交互和测试环境。要安装Selenium,执行以下命令:
pip install selenium
3. 环境配置
在进行自动化登录和滑动验证之前,需要对环境进行配置。我们需要先下载对应浏览器的驱动程序,以方便Selenium自动控制浏览器运行。本文以Chrome浏览器为例,可前往ChromeDriver下载页面下载对应版本的ChromeDriver。
下载完成后,将ChromeDriver所在目录添加到系统环境变量中。以Windows操作系统为例,在控制面板中找到环境变量设置,将ChromeDriver所在目录添加到Path中即可。
4. 代码编写
4.1 导入模块
首先,我们需要导入需要用到的模块。本文使用的是Python3,可以使用以下代码导入:
import cv2
import numpy as np
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
4.2 配置浏览器和登录账号
接下来,我们需要配置浏览器和登录账号。我们选择的是Chrome浏览器,可以使用以下代码进行配置:
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('lang=zh_CN.UTF-8')
driver = webdriver.Chrome(options=options)
上述代码中,我们使用ChromeOptions设置了headless模式和禁用GPU加速,并将语言设置为中文。
现在,我们需要设置登录账号信息,包括邮件地址、密码和登录页URL:
email_address = 'your_email_address'
password = 'your_password'
driver.get('https://mail.qq.com/cgi-bin/loginpage')
4.3 模拟滑块验证
现在,我们需要在自动化登录的基础上,解决滑块验证码的问题。首先,我们需要定位验证码的图片和滑块位置,并获取它们的坐标。
可视化的方式可以让我们快速确定需要处理的图像区域。如果您是在本地运行代码,可以使用以下代码将浏览器窗口截图并保存为本地文件:
driver.save_screenshot('screenshot.png')
4.4 图像处理
接下来,我们需要使用OpenCV对验证码图片进行处理。本文中,我们使用的是canny算法来检测边缘。可以使用以下代码:
src = cv2.imread('screenshot.png')
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3, 3), 0)
dst = cv2.Canny(blur, 3, 3 * 3)
cv2.imwrite('result.png', dst)
上述代码中,我们使用了cvtColor方法将BGR格式转为灰度图像,使用GaussianBlur方法对图像进行了降噪处理,然后使用Canny方法进行边缘检测。
4.5 滑块位置计算
在完成了边缘检测之后,我们可以使用HoughLinesP方法找出所有可能是滑块的线,然后计算滑块位置。
以下是代码:
minLineLength = 100
maxLineGap = 10
lines = cv2.HoughLinesP(dst, 1, np.pi / 180, 100, minLineLength, maxLineGap)
for x1, y1, x2, y2 in lines[:, 0, :]:
if y1 > 150:
slider_pos = (x1, y1, x2, y2)
break
使用以上代码,我们成功找到了滑块的位置。在上述代码中,我们使用的是直线长度和直线之间的间隙作为参数来避免无关直线的影响。
4.6 移动滑块
现在,我们已经确定了滑块位置,我们可以通过模拟鼠标操作来拖动滑块。以下是基本操作:
slider = driver.find_element_by_xpath('//div[@id="tcaptcha_drag_thumb"]')
ActionChains(driver).drag_and_drop_by_offset(slider, slider_pos[2], slider_pos[3]).perform()
在上述代码中,我们使用x-path方法找到了滑块,并使用了drag_and_drop_by_offset方法来拖动滑块。其中,ActionChains类可以用来执行鼠标操作。
5. 完整代码
这里是完整的代码:
import cv2
import numpy as np
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
email_address = 'your_email_address'
password = 'your_password'
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('lang=zh_CN.UTF-8')
driver = webdriver.Chrome(options=options)
driver.get('https://mail.qq.com/cgi-bin/loginpage')
time.sleep(3)
driver.switch_to.frame("login_frame")
driver.find_element_by_id('u').send_keys(email_address)
driver.find_element_by_id('p').send_keys(password)
driver.find_element_by_id('login_button').click()
# wait for page to load
time.sleep(3)
# switch to captcha iframe
driver.switch_to.frame("tcaptcha_iframe")
# get image position and dimension
img = driver.find_element_by_xpath('//img[@id="slideBg"]')
loc = img.location
size = img.size
time.sleep(1)
# capture screenshot
driver.save_screenshot('screen.png')
# crop captcha image
x = loc['x']
y = loc['y'] + 54
width = size['width']
height = size['height'] - 90
im = cv2.imread('screen.png', cv2.IMREAD_COLOR)
im = im[y:y + height, x:x + width]
cv2.imwrite('captcha.png', im)
# get slider position
src = cv2.imread('screen.png')
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3, 3), 0)
dst = cv2.Canny(blur, 3, 3 * 3)
cv2.imwrite('result.png', dst)
minLineLength = 100
maxLineGap = 10
lines = cv2.HoughLinesP(dst, 1, np.pi / 180, 100, minLineLength, maxLineGap)
for x1, y1, x2, y2 in lines[:, 0, :]:
if y1 > 150:
slider_pos = (x1, y1, x2, y2)
break
# move slider
slider = driver.find_element_by_xpath('//div[@id="tcaptcha_drag_thumb"]')
ActionChains(driver).drag_and_drop_by_offset(slider, slider_pos[2], slider_pos[3]).perform()
driver.quit()
6. 总结
本文介绍了如何使用Python、OpenCV和Selenium自动化登录邮箱并解决滑动验证的问题。通过对浏览器的操作和图像处理,我们成功实现了自动化的登录,并模拟了滑块移动的操作。