使用crontab运行Selenium(python)

20 投票
5 回答
18866 浏览
提问于 2025-04-18 07:48

我有一个Python脚本,它通过Selenium来调用Chrome,代码是这样的:

 ff = webdriver.Chrome('/home/user01/webScraping/CollectAndGo/chromedriver')

这个Python脚本是从一个Shell脚本中调用的。

python /home/user01/webScraping/CollectAndGo/cgcom.py > /home/user01/webScraping/CollectAndGo/cgcom.log 2>&1

当我从终端运行这个脚本或者直接执行.sh文件时,一切都很顺利,但当我设置一个定时任务(crontab)时,就出现了错误。

   raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: u'unknown error: Chrome failed to start: exited abnormally\n  (Driver info: chromedriver=2.9.248304,platform=Linux 3.5.0-36-generic x86_64)' 

这个错误和我提问的第一行代码有关。有没有人知道这可能是什么原因呢?

5 个回答

-1

Crontab 可能是以一个没有权限访问 chromedriver 文件夹或文件的用户身份在运行。

可以看看 这里的回答,了解如何以特定用户身份运行 crontab。

0

Selenium网页驱动需要一个X会话来运行脚本。而定时任务(Cron脚本)通常是在没有X会话的情况下运行的。所以你需要在你的定时任务脚本中添加X会话。可以这样写:

* 11 * * * export DISPLAY=:0; your script.py

1

在MacOS Catalina上,只有这个命令对我有效。

* * * * * export DISPLAY=:0 && export PATH=$PATH:/usr/local/bin && /usr/bin/python3 ~/Documents/Scripts/my_script.py
4

使用 pyvirtualdisplay 和 Xvfb 来帮你管理窗口会话(这个方法最初来自 这个回答

背景:

在我的情况下,之前的答案没有奏效。

解决方案:

  1. 安装 PyVirtualDisplay 和 Xvfb
pip3 install pyvirtualdisplay
sudo apt-get install xvfb
  1. 在你的 .py 脚本中分配窗口处理器
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from pyvirtualdisplay import Display
import time

# Display creates a virtual frame buffer and manages it for you
with Display(visible=False, size=(1200, 1500)):
    driver = webdriver.Firefox()
    driver.get("https://website-target.com")

    time.sleep(1)

    print(driver.current_url) # check connection

    time.sleep(1)

    print(driver.current_url)

    driver.close()

36

cron 启动浏览器时,最明显的问题是即使你的机器上运行着 X 窗口系统,来自 crontab 的进程也没有设置 DISPLAY 环境变量,这样从那里启动浏览器就会失败。

解决方案有简单的,也有复杂的。简单的解决办法是接受如果没有 X 运行,脚本就不会执行,并手动将 DISPLAY 设置为 :0,这是 Ubuntu 启动的默认 X 服务器的显示编号。

例如,如果我在 crontabcommand 列中放入这个命令,Chrome 就能正常启动:

DISPLAY=:0 google-chrome

在用户特定的 crontab 文件中,完整的行可能是这样的:

0 * * * *  DISPLAY=:0 google-chrome

如果你想运行一个通过 selenium 启动 Chrome 的 Python 脚本,那么这一行应该是:

0 * * * *  DISPLAY=:0 python my_script.py

这个命令字符串会原封不动地发送给 shell,所以在最后一个例子中,字符串 DISPLAY=:0 python my_script.py 会直接传给 shell。常见的 shell 语法是将命令开头的变量赋值视为设置环境变量。(这对于 dashbash 是成立的,这两者中大多数安装的默认 shell 可能是其中之一。)所以 shell 解释的命令会将环境变量 DISPLAY 设置为 :0,然后运行 python my_script.py。由于 python 从启动它的 shell 继承环境,因此对它来说,DISPLAY 变量也是 :0

像我上面展示的那样设置 DISPLAY=:0 只会为后面的命令设置这个变量。也可以将 DISPLAY 设置为 :0,使 crontab 执行的所有命令都使用这个值。例如,在以下用户特定的 crontab 中:

DISPLAY=:0

30 * * * *  google-chrome
0  * * * *  python my_script.py

这一行 DISPLAY=:0 会为执行 google-chromepython my_script.py 设置环境变量 DISPLAY

撰写回答