首頁  >  文章  >  後端開發  >  如何使用 systemd 將 Selenium 設定為 Linux 守護進程

如何使用 systemd 將 Selenium 設定為 Linux 守護進程

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-10-18 18:17:29535瀏覽

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. 參考文獻


安裝Google瀏覽器

首先,更新所有軟體包。

sudo apt update

下載穩定的 Google Chrome 軟體包。

wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb

安裝Google瀏覽器。

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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn