使用 selenium 库 模拟浏览器事件

启动方式

一键启动脚本(windows下)

下面py脚本命名为萝卜dst服务器一键启动.py

创建一键启动脚本一键启动.bat 注意有中文,编码要转为ANSI编码

@echo off
echo 正在启动脚本...
python ./萝卜dst服务器一键启动.py
echo 脚本执行完毕。

定时任务启动(linux下)

在 Debian 系统中,可以使用 cron 服务来定时执行任务。cron 是一个定时任务调度器,非常适合用来安排定期执行的脚本。下面是如何使用 cron 来每天早上7点定时启动你的 Selenium 脚本。

步骤

  1. 编写脚本文件:首先,将你的 Selenium 脚本保存为一个 Python 文件,例如 selenium_script.py

  2. 确保脚本可执行:给脚本文件加上可执行权限。

    chmod +x selenium_script.py
  3. 编辑 crontab 文件:使用 crontab -e 命令编辑当前用户的定时任务。

    crontab -e
  4. 添加定时任务:在 crontab 文件中添加一行,指定每天早上7点执行你的脚本。

    0 7 * * * /usr/bin/python3 /path/to/selenium_script.py

解释:

  • 0 7 * * * 表示每天早上7点。

  • /usr/bin/python3 是 Python 3 的路径,确保路径正确。

  • /path/to/selenium_script.py 是你的脚本文件的完整路径。

debug

隐藏浏览器版本(无头模式)(推荐使用)

import logging
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from selenium.webdriver.chrome.options import Options

# 设置 Chrome 选项
chrome_options = Options()
chrome_options.add_argument('--headless')  # 启用无头模式
chrome_options.add_argument('--disable-gpu')  # 禁用GPU加速(某些系统上可能需要)

# 配置日志记录
logging.basicConfig(filename='log.txt', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 启动浏览器
driver = webdriver.Chrome(options=chrome_options)

try:
    # 访问登录页面
    driver.get("http://dstyun.cn/login")
    logging.info("访问登录页面")

    # 等待输入框出现
    WebDriverWait(driver, 10).until(
        EC.presence_of_all_elements_located((By.CLASS_NAME, "el-input__inner"))
    )
    logging.info("输入框已找到")

    # 获取所有 class 为 "el-input__inner" 的元素
    input_elements = driver.find_elements(By.CLASS_NAME, "el-input__inner")

    # 假设第一个元素是用户名输入框,第二个元素是密码输入框
    username_input = input_elements[0]
    password_input = input_elements[1]

    # 输入用户名和密码
    username_input.send_keys("用户名")
    password_input.send_keys("密码")
    logging.info("用户名和密码已输入")

    # 等待登录按钮出现并点击
    login_button = WebDriverWait(driver, 5).until(
        EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'el-button') and contains(@class, 'el-button--primary') and contains(@class, 'el-button--medium')]"))
    )
    login_button.click()
    logging.info("登录按钮已点击")

    # 等待页面加载完成,确保登录成功
    WebDriverWait(driver, 10).until(
        EC.url_changes("http://dstyun.cn/login")  # 假设登录成功后 URL 会变化
    )
    logging.info("登录成功,URL 已变化")

    # 获取当前页面的所有 Cookie
    cookies = driver.get_cookies()
    logging.info("获取到的 Cookie: %s", cookies)

    # 等待状态元素出现
    try:
        WebDriverWait(driver, 5).until(  # 增加超时时间
            EC.presence_of_all_elements_located((By.XPATH, "//div[@class='el-col el-col-24 el-col-xs-12 el-col-sm-12 el-col-md-12 el-col-lg-10 el-col-xl-8 myline']"))
        )
        logging.info("状态元素已找到")
    except TimeoutException:
        logging.warning("状态元素未在规定时间内出现")

    # 等待状态元素出现
    try:
        status_elements = WebDriverWait(driver, 5).until(  # 增加超时时间
            EC.presence_of_all_elements_located((By.XPATH, "//div[@class='el-col el-col-24 el-col-xs-6 el-col-sm-6 el-col-md-4 el-col-lg-4 el-col-xl-4 myline']"))
        )
        logging.info("状态元素已找到")
    except TimeoutException:
        logging.warning("状态元素未在规定时间内出现")
        raise

    # 检查状态元素的文本内容
    status_texts = [element.text for element in status_elements]
    logging.info("状态文本: %s", status_texts)

    # 检查是否所有状态都是“已开启”,三个状态 已关闭,加载中,已开启
    all_opened = all(text != "已关闭" for text in status_texts)

    if not all_opened:
        # 等待重启按钮出现并点击
        try:
            restart_button = WebDriverWait(driver, 5).until(  # 增加超时时间
                EC.element_to_be_clickable((By.XPATH, "//button[.//span[text()='一键重启']]"))
            )
            restart_button.click()
            logging.info("一键重启按钮已点击")
        except TimeoutException:
            logging.warning("重启按钮未在规定时间内出现")
        except NoSuchElementException:
            logging.warning("未找到重启按钮")
    else:
        logging.info("所有状态均已开启,无需重启")

finally:
    # 关闭浏览器
    driver.quit()
    logging.info("浏览器已关闭")

不隐藏浏览器版本(有头模式)

import logging
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException, NoSuchElementException

# 配置日志记录
logging.basicConfig(filename='log.txt', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 启动浏览器
driver = webdriver.Chrome()

try:
    # 访问登录页面
    driver.get("http://dstyun.cn/login")
    logging.info("访问登录页面")

    # 等待输入框出现
    WebDriverWait(driver, 10).until(
        EC.presence_of_all_elements_located((By.CLASS_NAME, "el-input__inner"))
    )
    logging.info("输入框已找到")

    # 获取所有 class 为 "el-input__inner" 的元素
    input_elements = driver.find_elements(By.CLASS_NAME, "el-input__inner")

    # 假设第一个元素是用户名输入框,第二个元素是密码输入框
    username_input = input_elements[0]
    password_input = input_elements[1]

    # 输入用户名和密码
    username_input.send_keys("用户名")
    password_input.send_keys("密码")
    logging.info("用户名和密码已输入")

    # 等待登录按钮出现并点击
    login_button = WebDriverWait(driver, 5).until(
        EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'el-button') and contains(@class, 'el-button--primary') and contains(@class, 'el-button--medium')]"))
    )
    login_button.click()
    logging.info("登录按钮已点击")

    # 等待页面加载完成,确保登录成功
    WebDriverWait(driver, 10).until(
        EC.url_changes("http://dstyun.cn/login")  # 假设登录成功后 URL 会变化
    )
    logging.info("登录成功,URL 已变化")

    # 获取当前页面的所有 Cookie
    cookies = driver.get_cookies()
    logging.info("获取到的 Cookie: %s", cookies)

    # 等待状态元素出现
    try:
        WebDriverWait(driver, 5).until(  # 增加超时时间
            EC.presence_of_all_elements_located((By.XPATH, "//div[@class='el-col el-col-24 el-col-xs-12 el-col-sm-12 el-col-md-12 el-col-lg-10 el-col-xl-8 myline']"))
        )
        logging.info("状态元素已找到")
    except TimeoutException:
        logging.warning("状态元素未在规定时间内出现")

    # 等待状态元素出现
    try:
        status_elements = WebDriverWait(driver, 5).until(  # 增加超时时间
            EC.presence_of_all_elements_located((By.XPATH, "//div[@class='el-col el-col-24 el-col-xs-6 el-col-sm-6 el-col-md-4 el-col-lg-4 el-col-xl-4 myline']"))
        )
        logging.info("状态元素已找到")
    except TimeoutException:
        logging.warning("状态元素未在规定时间内出现")
        raise

    # 检查状态元素的文本内容
    status_texts = [element.text for element in status_elements]
    logging.info("状态文本: %s", status_texts)

    # 检查是否所有状态都是“已开启”,三个状态 已关闭,加载中,已开启
    all_opened = all(text != "已关闭" for text in status_texts)

    if not all_opened:
        # 等待重启按钮出现并点击
        try:
            restart_button = WebDriverWait(driver, 5).until(  # 增加超时时间
                EC.element_to_be_clickable((By.XPATH, "//button[.//span[text()='一键重启']]"))
            )
            restart_button.click()
            logging.info("一键重启按钮已点击")
        except TimeoutException:
            logging.warning("重启按钮未在规定时间内出现")
        except NoSuchElementException:
            logging.warning("未找到重启按钮")
    else:
        logging.info("所有状态均已开启,无需重启")

finally:
    # 关闭浏览器
    driver.quit()
    logging.info("浏览器已关闭")

初始版

隐藏浏览器版本(无头模式)

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options

# 设置 Chrome 选项
chrome_options = Options()
chrome_options.add_argument('--headless')  # 启用无头模式
chrome_options.add_argument('--disable-gpu')  # 禁用GPU加速(某些系统上可能需要)

# 启动浏览器
driver = webdriver.Chrome(options=chrome_options)

try:
    # 访问登录页面
    driver.get("http://dstyun.cn/login")

    # 等待输入框出现
    WebDriverWait(driver, 20).until(
        EC.presence_of_all_elements_located((By.CLASS_NAME, "el-input__inner"))
    )

    # 获取所有 class 为 "el-input__inner" 的元素
    input_elements = driver.find_elements(By.CLASS_NAME, "el-input__inner")

    # 假设第一个元素是用户名输入框,第二个元素是密码输入框
    username_input = input_elements[0]
    password_input = input_elements[1]

    # 输入用户名和密码
    username_input.send_keys("用户名")
    password_input.send_keys("密码")

    # 等待登录按钮出现并点击
    login_button = WebDriverWait(driver, 20).until(
        EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'el-button') and contains(@class, 'el-button--primary') and contains(@class, 'el-button--medium')]"))
    )
    login_button.click()

    # 等待页面加载完成,确保登录成功
    WebDriverWait(driver, 20).until(
        EC.url_changes("http://dstyun.cn/login")  # 假设登录成功后 URL 会变化
    )

    # 获取当前页面的所有 Cookie
    cookies = driver.get_cookies()

    # 打印所有 Cookie
    for cookie in cookies:
        print(cookie)

    # 等待元素出现
    WebDriverWait(driver, 20).until(
        EC.presence_of_all_elements_located((By.XPATH, "//div[@class='el-col el-col-24 el-col-xs-12 el-col-sm-12 el-col-md-12 el-col-lg-10 el-col-xl-8 myline']"))
    )
    
    # 等待状态元素出现
    status_elements = WebDriverWait(driver, 20).until(
        EC.presence_of_all_elements_located((By.XPATH, "//div[@class='el-col el-col-24 el-col-xs-6 el-col-sm-6 el-col-md-4 el-col-lg-4 el-col-xl-4 myline']"))
    )

    # 检查状态元素的文本内容
    status_texts = [element.text for element in status_elements]

    # 检查是否所有状态都是“已开启”
    all_opened = all(text == "已开启" for text in status_texts)

    if not all_opened:
        # 等待重启按钮出现并点击
        restart_button = WebDriverWait(driver, 20).until(
            EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'el-button') and contains(@class, 'el-button--success') and contains(@class, 'el-button--default') and @aria-disabled='false']"))
        )
        restart_button.click()
        print("一键重启按钮已点击")
    else:
        print("所有状态均已开启,无需重启")

finally:
    # 关闭浏览器
    driver.quit()

主要修改点:

  1. 添加 Chrome 选项:创建 Options 对象,并添加 --headless--disable-gpu 参数以启用无头模式。

  2. 传递选项:在启动 webdriver.Chrome 时,通过 options 参数传递 chrome_options

这样,浏览器将以无头模式运行,不会显示任何图形用户界面。

不隐藏浏览器版本(有头模式)

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 启动浏览器
driver = webdriver.Chrome()

try:
    # 访问登录页面
    driver.get("http://dstyun.cn/login")

    # 等待输入框出现
    WebDriverWait(driver, 20).until(
        EC.presence_of_all_elements_located((By.CLASS_NAME, "el-input__inner"))
    )

    # 获取所有 class 为 "el-input__inner" 的元素
    input_elements = driver.find_elements(By.CLASS_NAME, "el-input__inner")

    # 假设第一个元素是用户名输入框,第二个元素是密码输入框
    username_input = input_elements[0]
    password_input = input_elements[1]

    # 输入用户名和密码
    username_input.send_keys("用户名")
    password_input.send_keys("密码")

    # 等待登录按钮出现并点击
    login_button = WebDriverWait(driver, 20).until(
        EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'el-button') and contains(@class, 'el-button--primary') and contains(@class, 'el-button--medium')]"))
    )
    login_button.click()

    # 等待页面加载完成,确保登录成功
    WebDriverWait(driver, 20).until(
        EC.url_changes("http://dstyun.cn/login")  # 假设登录成功后 URL 会变化
    )

    # 获取当前页面的所有 Cookie
    cookies = driver.get_cookies()

    # 打印所有 Cookie
    for cookie in cookies:
        print(cookie)

    # 等待元素出现
    WebDriverWait(driver, 20).until(
        EC.presence_of_all_elements_located((By.XPATH, "//div[@class='el-col el-col-24 el-col-xs-12 el-col-sm-12 el-col-md-12 el-col-lg-10 el-col-xl-8 myline']"))
    )
    
    # 等待状态元素出现
    status_elements = WebDriverWait(driver, 20).until(
        EC.presence_of_all_elements_located((By.XPATH, "//div[@class='el-col el-col-24 el-col-xs-6 el-col-sm-6 el-col-md-4 el-col-lg-4 el-col-xl-4 myline']"))
    )

    # 检查状态元素的文本内容
    status_texts = [element.text for element in status_elements]

    # 检查是否所有状态都是“已开启”
    all_opened = all(text == "已开启" for text in status_texts)

    if not all_opened:
        # 等待重启按钮出现并点击
        restart_button = WebDriverWait(driver, 20).until(
            EC.element_to_be_clickable((By.XPATH, "//button[contains(@class, 'el-button') and contains(@class, 'el-button--success') and contains(@class, 'el-button--default') and @aria-disabled='false']"))
        )
        restart_button.click()
        print("一键重启按钮已点击")
    else:
        print("所有状态均已开启,无需重启")

finally:
    # 关闭浏览器
    driver.quit()

区别

隐藏浏览器(即启用无头模式)与不隐藏浏览器(正常模式)在使用 Selenium 进行自动化时有以下几个主要的区别:

1. 用户界面

  • 不隐藏:浏览器会像普通用户一样打开,显示完整的用户界面,可以看到页面加载的过程和交互效果。

  • 隐藏:浏览器以无头模式运行,不会显示任何图形用户界面,所有操作都在后台完成。

2. 性能

  • 不隐藏:因为需要渲染图形用户界面,可能会占用更多的 CPU 和内存资源。

  • 隐藏:无需渲染图形界面,通常可以更快地执行脚本,占用更少的资源。

3. 调试

  • 不隐藏:可以直观地看到脚本执行过程中的每一个步骤,便于发现和解决问题。

  • 隐藏:无法直接观察到脚本的执行情况,调试时需要依赖日志输出或截图等手段。

4. 安全性

  • 不隐藏:可能更容易被网站检测到是自动化工具,因为一些行为可能不符合真实用户的习惯。

  • 隐藏:虽然无头模式下的浏览器行为也可能被检测到,但一些网站可能对无头模式下的请求处理有所不同,有时可以帮助绕过某些检测机制。

5. 适用场景

  • 不隐藏:适用于需要观察脚本执行过程的开发和测试阶段,或者在演示和教学中展示自动化过程。

  • 隐藏:适合于生产环境中的定时任务、后台作业、大规模数据抓取等不需要用户界面的情况。

6. 兼容性

  • 不隐藏:大多数情况下,正常的浏览器模式可以更好地模拟真实用户的行为,因此在兼容性方面表现更好。

  • 隐藏:某些网站可能对无头模式下的请求有特殊的处理逻辑,导致某些功能无法正常使用。不过,现代浏览器的无头模式已经相当成熟,大部分情况下都能正常工作。

总结

选择是否隐藏浏览器取决于具体的使用场景和需求。如果你需要快速、高效地执行任务并且不在意可视化反馈,那么启用无头模式是一个不错的选择。如果你需要进行详细的调试或向他人展示自动化过程,那么不隐藏浏览器会更加合适。