一、工具简介
在日常工作中,我们经常需要重复登录某些网站进行操作。手动登录不仅效率低下,而且容易出错。本文将介绍一个基于Selenium的自动化登录脚本,可以帮助我们高效完成登录操作。
1.1、这个Python脚本主要实现了以下功能:
- 自动配置Chrome浏览器选项
- 使用环境变量存储敏感信息(用户名和密码)
- 智能等待页面元素加载
- 自动填写登录表单并提交
- 完善的错误处理和日志记录
1.2、配置浏览器选项表格
| 代码 | 作用 | 说明 |
|---|---|---|
| --disable-blink-features=AutomationControlled | 隐藏自动化特征 | 绕过反爬虫检测 |
| excludeSwitches: ["enable-automation"] | 隐藏“自动化控制”提示栏 | 避免被网站识别为爬虫 |
| --start-maximized | 启动时最大化窗口 | 确保所有元素可见 |
| --disable-notifications | 禁用通知弹窗 | 避免干扰自动化流程 |
1.3、游览器驱动初始化方法
| 代码 | 说明 |
|---|---|
| webdriver.Chrome() | 默认本地驱动版本 |
| webdriver.Chrome(service=Service(driver_path = ChromeDriverManager().install())) | 自动管理官方驱动版本 |
| dm= WDMDownloadManager() | 自动管理国内镜像驱动版本A |
| load_url = "https://npm.taobao.org/mirrors/chromedriver/" | 自动管理国内镜像驱动版本B |
| driver_path = ChromeDriverManager(url=load_url,download_manager=dm).install() | 自动管理国内镜像驱动版本C |
| webdriver.Chrome(service=Service(driver_path),options=chrome_options) | 自动管理国内镜像驱动版本D |
二、核心代码解析
2.1、浏览器配置
def _configure_browser(self):
"""配置浏览器选项"""
self.chrome_options.add_argument("--disable-blink-features=AutomationControlled")
self.chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
self.chrome_options.add_argument("--start-maximized")
self.chrome_options.add_argument("--disable-notifications")
这段代码设置了Chrome浏览器的几个重要选项:
- 禁用自动化控制特征,避免被网站识别为爬虫
- 隐藏"自动化控制"提示栏
- 启动时最大化窗口
- 禁用通知弹窗
2.2、元素等待机制
def _wait_for_element(self, by, locator, timeout=10, clickable=False):
try:
if clickable:
return WebDriverWait(self.driver, timeout).until(
EC.element_to_be_clickable((by, locator))
return WebDriverWait(self.driver, timeout).until(
EC.presence_of_element_located((by, locator)))
except TimeoutException:
logging.error(f"元素定位超时: {locator}")
raise
这个方法封装了Selenium的等待机制,可以智能等待元素出现或变为可点击状态,避免了因页面加载慢导致的元素找不到的问题。
2.3、实例功能流程
def login(self, login_url):
# 初始化驱动
if not self.init_driver():
return False
try:
# 从环境变量获取凭证
username = os.getenv("YOUUSER")
password = os.getenv("YOUPWD")
# 打开登录页面
self.driver.get(login_url)
self.driver.maximize_window()
# 定位元素并填写表单
username_field = self._wait_for_element(By.XPATH, "//input[@type='text' and @placeholder='登录名或手机号']")
password_field = self._wait_for_element(By.XPATH, "//input[@type='password']")
checkbox_field = self._wait_for_element(By.CSS_SELECTOR,"input[type='checkbox']")
username_field.clear()
username_field.send_keys(username)
password_field.clear()
password_field.send_keys(password)
# 处理复选框
if not checkbox_field.is_selected():
checkbox_field.click()
# 提交表单
login_button = self._wait_for_element(By.CSS_SELECTOR, "[class*='loginButton'] button", clickable=True)
login_button.click()
return True
except Exception as e:
logging.error(f"登录过程中出错: {str(e)}")
self.driver.save_screenshot("login_error.png")
return False
2.4、完整实例代码
#!/usr/bin/python
# -*- coding: utf-8 -*-
# @Users: LiMu
# @Files: login_selenium.py
# @Times: 2025/6/19
# @Software: PyCharm
import os
import logging
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from webdriver_manager.chrome import ChromeDriverManager
from webdriver_manager.core.download_manager import WDMDownloadManager
# 配置日志
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(message)s",
handlers=[logging.StreamHandler()]
)
class WebAutomation:
def __init__(self):
self.driver = None
self.chrome_options = Options()
self._configure_browser()
def _configure_browser(self):
"""配置浏览器选项"""
self.chrome_options.add_argument("--disable-blink-features=AutomationControlled")
self.chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"])
self.chrome_options.add_argument("--start-maximized")
self.chrome_options.add_argument("--disable-notifications")
def _wait_for_element(self, by, locator, timeout=10, clickable=False):
"""
等待元素出现或可点击
:param by: 定位方式 (By.XPATH/By.ID等)
:param locator: 定位器
:param timeout: 超时时间(秒)
:param clickable: 是否要求元素可点击
:return: WebElement
"""
try:
if clickable:
return WebDriverWait(self.driver, timeout).until(
EC.element_to_be_clickable((by, locator))
)
return WebDriverWait(self.driver, timeout).until(
EC.presence_of_element_located((by, locator))
)
except TimeoutException:
logging.error(f"元素定位超时: {locator}")
raise
except Exception as e:
logging.error(f"等待元素时发生错误: {str(e)}")
raise
def init_driver(self):
try:
driver_path = ChromeDriverManager(
url="https://npm.taobao.org/mirrors/chromedriver/",
download_manager=WDMDownloadManager()
).install()
self.driver = webdriver.Chrome(
service=Service(driver_path),
options=self.chrome_options
)
logging.info("浏览器驱动初始化成功")
return True
except Exception as e:
logging.error(f"驱动初始化失败: {str(e)}")
return False
def login(self, login_url):
"""执行登录操作"""
if not self.init_driver():
return False
try:
username = os.getenv("YOUUSER")
password = os.getenv("YOUPWD")
self.driver.get(login_url)
self.driver.maximize_window()
logging.info("已打开登录页面")
#定位元素
user_xpath = "//input[@type='text' and @placeholder='登录名或手机号']"
pwd_xpath = "//input[@type='password']"
login_btn_xpath = "[class*='loginButton'] button"
checkbox_xpath ="input[type='checkbox']"
# 使用封装的等待方法等待需要操作的元素出现再进行下一步操作
username_field = self._wait_for_element(By.XPATH, user_xpath)
password_field = self._wait_for_element(By.XPATH, pwd_xpath)
checkbox_field = self._wait_for_element(By.CSS_SELECTOR,checkbox_xpath)
#清空账密输入框数据并输入新的账户密码信息
username_field.clear()
username_field.send_keys(username)
password_field.clear()
password_field.send_keys(password)
#判断记录登录名勾选是否勾选,没有勾选则点击勾选
if not checkbox_field.is_selected():
checkbox_field.click()
logging.info("已填写用户名和密码")
self.driver.save_screenshot("login_user_pwd.png")
#如果功能表单在iframe中,需要先切换到iframe
# iframe = self.driver.find_element(By.TAG_NAME, "iframe")
# self.driver.switch_to.frame(iframe)
# 这里写功能操作的代码
# self.driver.switch_to.default_content()
login_button = self._wait_for_element(By.CSS_SELECTOR, login_btn_xpath, clickable=True)
login_button.click()
logging.info("登录请求已提交")
return True
except TimeoutException as e:
logging.error(f"登录超时: {str(e)}")
self.driver.save_screenshot("login_timeout.png")
return False
except Exception as e:
logging.error(f"登录过程中出错: {str(e)}")
self.driver.save_screenshot("login_error.png")
return False
def close(self):
"""关闭浏览器"""
if self.driver:
self.driver.quit()
logging.info("浏览器已关闭")
if __name__ == '__main__':
automation = WebAutomation()
try:
automation.login("https://sh.***xt.com/account/login")
finally:
input("按回车键退出浏览器...")
automation.close()
三、使用说明
- 将用户名和密码设置为环境变量:
①YOUUSER: 用户名 ②YOUPWD: 密码
- 安装依赖:
# 安装Selenium核心库
pip install selenium
# 安装WebDriver管理器(用于自动管理浏览器驱动)
pip install webdriver-manager
四、总结
这个自动化登录脚本展示了如何使用Selenium实现一个健壮的网页自动化工具。通过合理的封装和错误处理,可以大大提高自动化任务的可靠性。读者可以根据自己的需求修改和扩展这个脚本,实现更复杂的自动化操作。