如何使用 systemd 将 Selenium 设置为 Linux 守护进程

Mary-Kate Olsen
发布: 2024-10-18 18:17:29
原创
426 人浏览过

How to Set Up Selenium as a Linux Daemon with systemd

在 ubuntu 或 debian 上设置并运行 Chrome 和 Selenium。本指南基于 ubuntu 22.04

Selenium 非常适合自动化 Web 任务,但让机器人在服务器上 24/7 运行可能很棘手。通过使用 systemd,您可以将 Selenium 机器人作为后台服务(守护进程)运行,确保其可靠运行并在失败时重新启动。本指南将引导您完成设置步骤,重点是针对 Linux VPS 配置它。

目录

  1. 安装 Google Chrome

  2. 设置虚拟环境

  3. 安装必要的软件包

  4. 创建 Python 脚本

  5. 设置 systemd 服务

    • 添加 ENV 变量(可选)
    • 服务文件
    • 运行服务
  6. 修复块缓冲问题

    • 使用 -u 标志
    • 使用打印刷新参数
  7. 使用journalctl访问日志

  8. 参考文献


安装谷歌浏览器

首先,更新所有软件包。

sudo apt update
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

下载稳定的 Google Chrome 软件包。

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
登录后复制
登录后复制
登录后复制
登录后复制

安装谷歌浏览器。

sudo apt install -y ./google-chrome-stable_current_amd64.deb
登录后复制
登录后复制
登录后复制
登录后复制

检查已安装的 Google Chrome 版本。

google-chrome --version
登录后复制
登录后复制
登录后复制
登录后复制

设置虚拟环境

如果您仅在计算机上运行 Selenium 机器人,则这些步骤不是强制性的。但是,如果您正在处理其他项目或需要隔离环境,则建议您这样做。

让我们创建我们的虚拟环境。

python3 -m venv venv
登录后复制
登录后复制
登录后复制
登录后复制

激活虚拟环境。

source venv/bin/activate
登录后复制
登录后复制

安装必要的包

现在,安装 selenium 和 webdriver-manager。

pip install selenium
pip install webdriver-manager
登录后复制

webdriver-manger 的目的是简化不同浏览器的二进制驱动程序的管理。您可以在其文档中了解更多信息。


创建 Python 脚本

## main.py

from selenium import webdriver
## ---- Use for type hint ---- ##
from selenium.webdriver.chrome.webdriver import WebDriver
## --------------------------- ##
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from webdriver_manager.chrome import ChromeDriverManager


def create_chrome_web_driver_connection(headless: bool,
                                       detach:bool,
                                       use_sandbox: bool,
                                       use_dev_shm: bool,
                                       window_width: int = 1052,
                                       window_height: int = 825
                                       ) -> WebDriver:

    service = Service(ChromeDriverManager().install())
    options = Options()
    options.add_experimental_option("detach", detach)
    options.add_argument(f"--window-size={window_width},{window_height}")
    options.add_argument("--disable-extensions")
    options.add_argument("--disable-renderer-backgrounding")
    options.page_load_strategy = 'normal'

    if not use_sandbox:
        options.add_argument('--no-sandbox')
    if not use_dev_shm:
        options.add_argument('--disable-dev-shm-usage')
    if headless:
        options.add_argument("--headless=new")

    driver = webdriver.Chrome(service= service, options=options)

    return driver



if "__main__" == __name__:
    driver =  create_chrome_web_driver_connection(headless= True,
                                                 detach= False,
                                                 use_sandbox= False,
                                                 use_dev_shm= False)

    driver.get('https://python.org')
    print(driver.title)

    driver.close()

登录后复制

options.add_experimental_option("detach", detach) :

  • 这允许您配置 Chrome 浏览器在脚本执行完成后是否保持打开状态。
  • 如果 detach 为 True,即使 WebDriver 会话结束,浏览器窗口也将保持打开状态。

options.add_argument(f"--window-size={window_width},{window_height}") :

  • 这会根据宽度和高度设置浏览器的窗口大小。

如果您愿意,您可以删除此行。
如果您计划在无头模式下运行 Selenium,请确保以这种方式设置窗口大小;否则,根据我的经验,默认窗口大小可能太小。

您可以使用此命令 driver.get_window_size() 检查窗口大小

options.add_argument("--disable-extensions") :

  • 扩展程序可能会干扰自动浏览器交互,因此禁用它们可以提高稳定性。

options.add_argument("--disable-renderer-backgrounding") :

  • 这可以防止 Chrome 取消优先级或暂停后台选项卡。
  • 这在跨多个选项卡执行操作时非常有用。

options.page_load_strategy = '正常' :

  • 这会将页面加载策略设置为正常,这意味着 Selenium 将等待页面完全加载,然后再继续执行进一步的命令。
  • 其他选项包括 eager(等到 DOMContentLoaded 事件)和 none(不等待页面加载),您可以在这里了解更多信息。

options.add_argument('--no-sandbox') :

  • 沙箱是 Chrome 的一项安全功能,可隔离浏览器的进程。
  • 禁用它(--no-sandbox)在某些测试环境中(例如,在 Docker 容器中或以 root 用户身份执行脚本时)非常有用,因为沙箱会导致权限问题或崩溃。

options.add_argument('--disable-dev-shm-usage') :

  • /dev/shm 是 Linux 环境中经常使用的共享内存空间。默认情况下,Chrome 会尝试使用它来提高性能。
  • 禁用此选项(--disable-dev-shm-usage)可以防止共享内存有限的环境中发生崩溃。

options.add_argument("--headless=new") :

  • 这将启用无头模式,无需 GUI 即可运行 Chrome。
  • 无头模式对于在没有显示器的环境中运行非常有用,例如 CI/CD 管道或远程服务器。

设置系统服务

添加 ENV 变量(可选)

如果您的 selenium 程序需要使用环境变量,有两种方法可以实现此目的:

  1. 将 .env 文件与 python-dotenv 等库一起使用(更常见/流行的方法)。

  2. 使用 systemd 的内置选项来设置环境文件。

在此示例中,我们将使用第二个选项。

首先,让我们在 /etc 目录中创建一个 conf.d 目录。

sudo apt update
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

接下来,创建一个纯文本文件(这将是我们的环境文件)。

sudo apt update
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

现在您可以将环境变量添加到我们刚刚创建的文件中。

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
登录后复制
登录后复制
登录后复制
登录后复制

修改Python脚本以使用环境变量。

sudo apt install -y ./google-chrome-stable_current_amd64.deb
登录后复制
登录后复制
登录后复制
登录后复制

服务档案

您需要在 /etc/systemd/system/ 目录中创建一个服务文件;这是系统管理员安装的 systemd 单元应该放置的位置。

google-chrome --version
登录后复制
登录后复制
登录后复制
登录后复制

对于此示例,我将假设您位于 VPS 中并且希望以 root 用户身份运行该服务。

[!警告]
该服务将以 root(管理员)权限运行。这使其能够完全访问系统,但除非出于安全原因,否则通常会避免以 root 身份运行。

将其添加到服务文件中。

python3 -m venv venv
登录后复制
登录后复制
登录后复制
登录后复制

[单位] 部分

此部分定义服务的元数据和依赖项。

Description=Selenium Bot Service:提供服务功能的简短描述。在本例中,它将其描述为“Selenium Bot Service”。此描述用于系统日志和 systemctl 来识别服务。

After=network.target:这确保服务仅在网络可用后启动。 network.target 是一个 systemd 目标,表示基本网络功能已启动。

[服务]栏目

这部分指定服务本身的配置,包括它如何运行、哪个用户运行它以及如果失败该怎么办。

User :指定运行服务的用户。在这里,它被设置为root。

EnvironmentFile :指定包含服务使用的环境变量的文件。

WorkingDirectory:指定运行服务的目录。这是服务进程的工作目录。这里,bot 文件存储在 /root/selenium_bot/

ExecStart :定义启动服务的命令。在这里,它运行 /root/selenium_bot/

中的 main.py 文件

Restart=on-failure :将服务配置为在因失败退出(即非零退出状态)时自动重新启动。这对于确保机器人服务保持运行非常有用,即使偶尔出现故障也是如此。

RestartSec=5s :指定发生故障时重新启动之间的延迟。在这种情况下,服务将等待 5 秒,然后在失败后尝试重新启动。

StandardOutput=journal :将服务的标准输出(stdout)重定向到 systemd 日志,可以使用journalctl 查看该日志。这对于日志记录和调试目的很有用。

StandardError=journal :将标准错误 (stderr) 输出重定向到 systemd 日志。服务遇到的任何错误都将被记录下来,也可以使用journalctl

查看

[安装]部分

本节定义如何以及何时启用或启动服务。

WantedBy=multi-user.target :指定应启用服务的目标。在这种情况下,multi-user.target 是系统处于非图形多用户模式(常见于服务器)时到达的 systemd 目标。这意味着该服务将在系统达到此目标时启动,通常是在系统启动到多用户环境时启动。

要了解有关 systemd 服务的所有可能设置的更多信息,请查看参考资料

运行服务

让我们检查一下我们的服务文件是否有效;如果一切正常,则不应显示任何内容。

sudo apt update
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

重新加载 systemd 配置,寻找新的或修改的单元(服务)。

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
登录后复制
登录后复制
登录后复制
登录后复制

启动/重新启动您的服务。

sudo apt install -y ./google-chrome-stable_current_amd64.deb
登录后复制
登录后复制
登录后复制
登录后复制

停止服务。

google-chrome --version
登录后复制
登录后复制
登录后复制
登录后复制

检查您的服务状态。

python3 -m venv venv
登录后复制
登录后复制
登录后复制
登录后复制

如果您希望服务在启动时自动启动,请执行此操作。

source venv/bin/activate
登录后复制
登录后复制

修复块缓冲问题

在 python 中,当您在交互式环境中运行脚本时(例如,当您在终端中手动运行 python3 filename.py 时),Python 使用行缓冲。这意味着输出(如 print() 语句中的输出)会立即显示。

但是,当Python程序在非交互式环境中运行时(这是我们的情况),输出将使用块缓冲。这意味着程序将在缓冲区中保留其输出,直到缓冲区已满或程序结束,从而延迟您可以看到日志/输出的时间。

您可以在此处了解有关 python 输出缓冲如何工作的更多信息。

由于我们想要实时查看日志和输出,因此我们可以通过两种方式解决这个问题。

使用 -u 标志

python3 文档告诉我们这一点。

-u 强制 stdout 和 stderr 流不被缓冲。 此选项对标准输入流没有影响

通过使用 -u 标志,Python 以完全无缓冲的模式运行 stdout 和 stderr。这意味着每个字节一生成就会直接发送到终端(或任何输出流,如日志文件)。根本不发生缓冲。

通常会进入标准输出的每个字符(例如来自 print() 语句或错误)都会立即逐字节写入,而无需等待完整的行或缓冲区累积。

要使用此选项,请像这样运行脚本:

sudo apt update
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

如果您选择此选项,请确保修改服务文件中的 ExecStart。

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
登录后复制
登录后复制
登录后复制
登录后复制

使用打印刷新参数

在Python中,print()函数默认缓冲其输出,这意味着它将输出存储在内存中,并且仅在缓冲区已满或程序结束时才将其写出。通过使用flush=True,您可以强制Python在调用print()之后立即刷新输出,确保输出立即出现。

sudo apt install -y ./google-chrome-stable_current_amd64.deb
登录后复制
登录后复制
登录后复制
登录后复制

使用journalctl访问日志

要查看 systemd 单元(服务)的完整日志历史记录,请使用以下命令。

google-chrome --version
登录后复制
登录后复制
登录后复制
登录后复制

要实时监控日志,请使用 -f 标志。这将仅显示最新的日记条目,并在附加到日记时不断打印新条目。

python3 -m venv venv
登录后复制
登录后复制
登录后复制
登录后复制

参考

  • https://github.com/password123456/setup-selenium-with-chrome-driver-on-ubuntu_debian
  • https://www.selenium.dev/documentation/webdriver/drivers/options/
  • https://www.lambdatest.com/blog/selenium-page-load-strategy/
  • https://pypi.org/project/webdriver-manager/
  • https://pypi.org/project/python-dotenv/
  • https://wiki.archlinux.org/title/Systemd
  • https://man.archlinux.org/man/systemctl.1
  • https://man.archlinux.org/man/systemd.service.5.en#EXAMPLES
  • https://man.archlinux.org/man/systemd-analyze.1
  • https://docs.python.org/3/using/cmdline.html#cmdoption-u
  • https://realpython.com/python-flush-print-output/
  • https://man.archlinux.org/man/journalctl.1

以上是如何使用 systemd 将 Selenium 设置为 Linux 守护进程的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!