排版还需要好好整理一下
之前在windows10上写了一键启动的py脚本,现在需要部署到我的Linux服务器上
有考虑用systemd,但感觉流程有些复杂,要创建好几个文件
所以最终决定使用cron服务
实际使用操作的步骤
新建脚本文件dstTimedStart.py
nano ~/Dev/dstTimedStart.py填写保存要执行的脚本
修改并规范后的代码
修改部分
将重复功能封装到函数中
增加重启失败循环重启功能
import time
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加速(某些系统上可能需要)
chrome_options.add_argument("--headless") # 启用无头模式
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--disable-gpu")
# 显式指定 Chrome 的路径
# chrome_options.binary_location = "/usr/bin/google-chrome"
# 配置日志记录
logging.basicConfig(filename='/root/Dev/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("room114514")
password_input.send_keys("1919180")
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, 10).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("状态元素已找到01")
except TimeoutException:
logging.warning("状态元素未在规定时间内出现01")
# 等待状态元素出现
try:
status_elements = WebDriverWait(driver, 10).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("状态元素已找到02")
except TimeoutException:
logging.warning("状态元素未在规定时间内出现02")
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, 10).until( # 增加超时时间
EC.element_to_be_clickable((By.XPATH, "//button[.//span[text()='一键重启']]"))
)
restart_button.click()
logging.info("一键重启按钮已点击")
time.sleep(30) #为了稳定点,改为20s
# 检测重启后状态
try:
status_elements = WebDriverWait(driver, 10).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)
except TimeoutException:
logging.warning("重启按钮未在规定时间内出现")
except NoSuchElementException:
logging.warning("未找到重启按钮")
else:
logging.info("所有状态均已开启,无需重启")
finally:
# 关闭浏览器
driver.quit()
logging.info("浏览器已关闭")
前一个版本
import time
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加速(某些系统上可能需要)
chrome_options.add_argument("--headless") # 启用无头模式
chrome_options.add_argument("--no-sandbox")
chrome_options.add_argument("--disable-dev-shm-usage")
chrome_options.add_argument("--disable-gpu")
# 显式指定 Chrome 的路径
# chrome_options.binary_location = "/usr/bin/google-chrome"
# 配置日志记录
logging.basicConfig(filename='/root/Dev/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("room114514")
password_input.send_keys("1919180")
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("一键重启按钮已点击")
time.sleep(20) #为了稳定点,改为20s
# 检测重启后状态
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)
except TimeoutException:
logging.warning("重启按钮未在规定时间内出现")
except NoSuchElementException:
logging.warning("未找到重启按钮")
else:
logging.info("所有状态均已开启,无需重启")
finally:
# 关闭浏览器
driver.quit()
logging.info("浏览器已关闭")修复BUG
抓虫,下面有问题,生成的log.txt不会在同级目录下,而是在root目录下,log.txt应该改成绝对路径
logging.basicConfig(filename='log.txt', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')改为
logging.basicConfig(filename='/root/Dev/log.txt', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')import time
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("room114514")
password_input.send_keys("1919180")
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("一键重启按钮已点击")
time.sleep(10)
# 检测重启后状态
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)
except TimeoutException:
logging.warning("重启按钮未在规定时间内出现")
except NoSuchElementException:
logging.warning("未找到重启按钮")
else:
logging.info("所有状态均已开启,无需重启")
finally:
# 关闭浏览器
driver.quit()
logging.info("浏览器已关闭")确保 dstTimedStart.py 脚本具有可执行权限。给脚本赋予权限
chmod +x ~/Dev/dstTimedStart.py配置cron服务
确保 cron 服务正在运行。你可以使用以下命令来检查 cron 服务的状态:
sudo systemctl status cron编辑 Crontab 文件
crontab -e每天早上6:31启动~/Dev路径下的dstTimedStart.py,在文件末尾添加:
31 6 * * * /usr/bin/python3 ~/Dev/dstTimedStart.py为了方便了解每次的启动情况,使用可以将脚本的输出重定向到文件来捕获任何错误信息或输出,这有助于调试问题。
31 6 * * * /usr/bin/python3 ~/Dev/dstTimedStart.py >> ~/Dev/dstTimedStart.log 2>&1py脚本中使用了log,通常查看同级目录下的log.txt来判断启动过程更多一些
环境安装
selenium库
由于脚本中使用了selenium模块,未安装的需要安装
sudo pip3 install seleniumpip包管理
未安装pip的安装pip
sudo apt-get update
sudo apt-get install python3-pip
安装完成后,您可以通过运行 Python 并尝试导入 selenium 来验证它是否已正确安装:
python3 -c "import selenium; print(selenium.__version__)"Google Chrome
安装Google Chrome
下载并安装Google Chrome
使用wget命令从Google的官方服务器下载Chrome的Debian安装包,然后使用dpkg命令进行安装。如果安装过程中出现依赖问题,可以使用apt-get命令来修复。
wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
sudo dpkg -i google-chrome-stable_current_amd64.deb
sudo apt-get install -f # 修复依赖问题
sudo dpkg -i google-chrome-stable_current_amd64.debChromeDriver
安装ChromeDriver
确定Chrome版本
ChromeDriver 的版本需要与安装的 Google Chrome 版本匹配。因此,首先检查已安装的 Google Chrome 版本:
google-chrome --versionroot@RainYun-vUQMSsZ0:~/Dev# google-chrome --version
Google Chrome 131.0.6778.204
参考教程:https://blog.csdn.net/qq_46315152/article/details/143290193
【链接】最新版本下载链接:Chrome for Testing availability
版本114及以下下载链接:https://chromedriver.storage.googleapis.com/index.html
下载ChromeDriver
wget https://storage.googleapis.com/chrome-for-testing-public/131.0.6778.204/linux64/chromedriver-linux64.zip解压并安装ChromeDriver
使用unzip命令解压下载的ChromeDriver压缩包,并将其移动到系统的可执行路径中(如/usr/local/bin/)。然后,给ChromeDriver赋予可执行权限。
unzip chromedriver-linux64.zip chromedriver
cd chromedriver-linux64
sudo mv chromedriver /usr/local/bin/
sudo chmod +x /usr/local/bin/chromedriver删除已经无用的chromedriver-linux64
rm -rf chromedriver-linux64在Linux系统中,包括Debian,tar命令本身并不直接支持解压zip格式的文件。tar命令主要用于处理.tar、.tar.gz、.tar.bz2等格式的压缩文件。
要解压zip文件,应使用unzip命令。以下是使用unzip命令解压zip文件的步骤:
验证 ChromeDriver 是否安装成功,运行以下命令:
chromedriver --versionroot@RainYun-vUQMSsZ0:~/Dev/chromedriver-linux64# chromedriver --version
ChromeDriver 131.0.6778.204 (52*****56f9b7853******0-refs/branch-heads/6778_155@{#7})
unzip工具
安装unzip工具
sudo apt-get update
sudo apt-get install unzipBUG修复
DevTools listening on ws://127.0.0.1:16225/devtools/browser/e**2-d**2-4**f-8*5-58******123
[15872:11480:1227/022035.023:ERROR:ssl_client_socket_impl.cc(878)] handshake failed; returned -1, SSL error code 1, net_error -100执行的时候会有报错,起初以为因为ssl协议的问题,但是加了头,没用
# --ignore-certificate-errors
# 此参数告诉Chrome浏览器在访问HTTPS网站时忽略SSL证书错误。
# 这意味着即使网站的SSL证书存在问题(如过期、不被信任等),
# 浏览器也不会显示警告信息,而是继续加载页面。
# 注意:在生产环境中使用此参数会降低安全性。
chrome_options.add_argument('--ignore-certificate-errors')
# --allow-insecure-localhost
# 此参数允许Chrome浏览器在localhost或127.0.0.1上加载具有不安全证书(如自签名证书)的HTTPS页面。
# 这通常用于开发环境,其中开发者可能需要在本地机器上测试HTTPS功能。
# 注意:同样,在生产环境中使用此参数也会降低安全性。
chrome_options.add_argument('--allow-insecure-localhost')后来发现可能是网站所有者添加了一点小料针对自动脚本,检测点击完一键启动后若瞬间关闭页面就启动失败,所以使用time.sleep(10)就能解决,本次错误排查花费了将近3h
加个头文件
import time在点击一键重启按钮后无条件等待10s
logging.info("一键重启按钮已点击")
time.sleep(10)笼统的安装步骤
安装cron服务
通常,Debian 系统默认已经安装了 cron 服务。如果未安装,可以通过以下命令进行安装:
sudo apt-get update
sudo apt-get install cron编辑 Crontab 文件
crontab -e如果是第一次运行,系统可能会要求你选择一个文本编辑器(如 nano 或 vim)。
这里我习惯用nano,所以输入1,回车。
添加定时任务
在打开的 crontab 文件中,按照以下格式添加定时任务:
* * * * * command_to_execute每个字段的含义如下:
第一个
*代表分钟(0-59)第二个
*代表小时(0-23)第三个
*代表一个月中的第几天(1-31)第四个
*代表月份(1-12)第五个
*代表星期几(0-7,0 和 7 都代表星期日)
command_to_execute 是你想要定时执行的命令或脚本。例如,如果你想每天凌晨 2 点执行 dstTimedStart.py 脚本,可以添加以下行:
0 2 * * * /usr/bin/python3 /path/to/your/dstTimedStart.py注意:确保 /usr/bin/python3 是你系统中 Python 3 的正确路径,/path/to/your/dstTimedStart.py 是你的脚本路径。
保存并退出编辑器
根据你选择的编辑器,保存并退出。在 nano 中,你可以按 Ctrl+O 保存,然后按 Ctrl+X 退出。在 vim 中,你可以按 :wq 保存并退出。
验证 Cron 任务
你可以通过以下命令查看当前用户的 crontab 任务,确保你的定时任务已经成功添加:
crontab -l此外,为了确保定时任务正常工作,你可以在添加任务后稍等片刻(比如等待几分钟),然后手动触发一次 cron 任务来测试它是否正常工作。
注意事项
定时任务可能会导致未保存的数据丢失,因此在设置定时任务之前,请确保你的工作环境能够处理这种情况,并提前保存所有重要数据。
如果你的脚本需要特定的工作目录或环境变量,请在 crontab 文件中使用
cd命令或设置相应的环境变量。你可以使用
>或>>将脚本的输出重定向到文件,以便稍后查看。
通过以上步骤,你就可以在 Debian 系统上使用 cron 服务来定时启动 dstTimedStart.py 脚本了。