用python在做数据采集过程中,经常需要用到模拟登录,经常遇到各种图片、文字甚至短信等验证,如果能通过脚本的方便实现验证,就可以自动帮我更高效地收集数据。Selenium 是一个开源的 Web 自动化测试工具,最初是为网站自动化测试而开发的。它支持多种编程语言(如 Python、Java、C# 等),能够模拟用户在浏览器中的操作,如点击、输入、滚动等。Selenium 的核心组件是 WebDriver,它通过浏览器驱动(如 ChromeDriver、GeckoDriver)与浏览器进行交互。
以下是使用 Python 的 Selenium 库实现模拟登录过程中滑块验证:
步骤 1:安装依赖库
确保已安装 Selenium 和浏览器驱动(如 ChromeDriver):
pip install selenium
最新版的chrome浏览器驱动下载地址如下:
https://storage.googleapis.com/chrome-for-testing-public/135.0.7049.42/win64/chromedriver-win64.zip
下载后解压将 chromedriver.exe 放在当前目录下,或者放在PATH环境变量指定的目录下。
步骤 2:初始化浏览器驱动
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# 初始化 Chrome 浏览器
options = webdriver.ChromeOptions()
options.add_argument("--disable-blink-features=AutomationControlled") # 禁用自动化检测
driver = webdriver.Chrome(executable_path='chromedriver', options=options)
driver.get("https://example.com/login") # 替换为目标登录页面
步骤 3:输入用户名和密码
# 定位并输入用户名
username = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "username")) # 替换为实际的用户名输入框 ID)
username.send_keys("your_username")
# 定位并输入密码
password = driver.find_element(By.ID, "password") # 替换为实际的密码输入框 ID
password.send_keys("your_password")
步骤 4:定位滑块元素
# 等待滑块元素加载
slider = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CLASS_NAME, "slider")) # 替换为实际的滑块类名)
# 获取滑块轨道的宽度(可能需要调整选择器)
track = driver.find_element(By.CLASS_NAME, "slider-track")
track_width = track.size['width']
步骤 5:生成模拟人类拖动的轨迹
def generate_move_track(distance):
"""
生成模拟人类拖动的轨迹(加速-减速)
:param distance: 需要拖动的总距离
:return: 移动轨迹列表
"""
track = []
current = 0
mid = distance * 0.8 # 前80%快速滑动,后20%慢速微调
t = 0.2
while current < distance:
if current < mid:
a = 2 # 加速度
else:
a = -3 # 减速度
v0 = 0
move = v0 * t + 0.5 * a * t**2
current += move
track.append(round(move))
t += 0.2
# 微调确保最终位置准确
overshoot = current - distance
if overshoot > 0:
track.append(-round(overshoot))
return track
track = generate_move_track(track_width)
步骤 6:执行滑块拖动操作
actions = ActionChains(driver)
actions.click_and_hold(slider).perform()
for move in track:
actions.move_by_offset(move, 0).perform()
# 添加随机延迟(0.05秒到0.3秒之间)
actions.pause(random.uniform(0.05, 0.3))
actions.release().perform()
步骤 7:验证登录是否成功
try:
# 检查是否跳转到登录后的页面(例如存在退出按钮)
WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.LINK_TEXT, "退出"))
)
print("登录成功!")
except Exception as e:
print("滑块验证失败:", str(e))
完整代码示例
import random
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
def simulate_slider_verification():
# 初始化浏览器
driver = webdriver.Chrome(executable_path='chromedriver')
driver.get("https://example.com/login")
try:
# 输入用户名密码
username = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "username"))
)
username.send_keys("your_username")
password = driver.find_element(By.ID, "password")
password.send_keys("your_password")
# 定位滑块
slider = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CLASS_NAME, "slider"))
)
# 生成轨迹
track = generate_move_track(300) # 假设需要拖动300像素
# 执行拖动
actions = ActionChains(driver)
actions.click_and_hold(slider).perform()
for move in track:
actions.move_by_offset(move, 0).pause(random.uniform(0.05, 0.3)).perform()
actions.release().perform()
# 验证结果
WebDriverWait(driver, 10).until(
EC.url_contains("/dashboard") # 检查是否跳转到仪表盘
)
print("登录成功!")
finally:
driver.quit()
def generate_move_track(distance):
# ...(同上轨迹生成函数)...
if __name__ == "__main__":
simulate_slider_verification()
关键注意事项
元素定位:需根据目标网站实际HTML结构调整定位方式(ID/CLASS/XPath)
轨迹模拟:调整generate_move_track参数以匹配不同距离的验证需求
反检测机制:
添加options.add_argument("--disable-blink-features=AutomationControlled")
使用随机延迟和移动轨迹
考虑使用无头模式时需更精确的轨迹模拟
异常处理:添加重试机制处理偶发验证失败
性能优化:对于复杂验证,可结合OpenCV进行缺口位置识别
高级技巧(应对复杂验证)
对于需要识别缺口位置的滑块(如拼图验证),需结合图像处理:
from PIL import Image
import cv2
import numpy as np
def detect_gap_position():
# 截取滑块背景图和缺口图
bg_img = Image.open('background.png')
gap_img = Image.open('gap.png')
# 转换为OpenCV格式
bg_cv = cv2.cvtColor(np.array(bg_img), cv2.COLOR_RGB2BGR)
gap_cv = cv2.cvtColor(np.array(gap_img), cv2.COLOR_RGB2BGR)
# 使用模板匹配查找缺口位置
result = cv2.matchTemplate(bg_cv, gap_cv, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
return max_loc[0] # 返回缺口x坐标
将图像识别与拖动操作结合使用,可应对更复杂的滑块验证场景。