在 CentOS7 上以无头模式使用 Selenium 和 Chromedriver 的 Python 脚本在手动调用时运行良好。
options = webdriver.ChromeOptions()
options.add_argument('headless')
options.add_argument('no-sandbox')
self.driver = webdriver.Chrome(chrome_options=options)
但是,当使用 crontab 启动脚本时,它会在第 4 行(上图(抛出此异常。底部的完整回溯。
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally (Driver info: chromedriver=2.38.552522
Cron 是用 crontab -e 设置
的* * * * * cd /to/path && /to/path/.virtualenvs/selenium/bin/python /to/path/script.py -t arg1 arg2 > /to/path/log.txt 2>&1
这会产生诸如找不到chromedriver之类的错误。然后我添加了以下内容到 crontab -e.
1( 使用 bash 而不是 sh,尽管从 sh 手动启动 python 脚本工作正常
2( 指定 chromedriver 的路径
SHELL=/bin/bash
PATH=/usr/local/bin/
我尝试了在网络上找到的不同建议,例如在我的脚本中向 chromedriver 添加 --no-sandbox 选项。一切都没有帮助。请注意,我在无头模式下使用 chrome,所以我认为我不需要在 cron 或 Xvfb 库中导出这个导出 DISPLAY=:0 的东西,就像以前一样
。Python 3.6.1
Selenium 3.4.3
Chromedriver 2.38.552522
google-chrome-stable 65.0.3325.181
完整回溯
Exception in thread <name>:
Traceback (most recent call last):
File "/usr/lib64/python3.6/threading.py", line 916, in _bootstrap_inner
self.run()
File "/usr/lib64/python3.6/threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "/path/to/script.py", line 53, in start
self.site_scrape(test_run)
File "/path/to/script.py", line 65, in site
self.driver = webdriver.Chrome(chrome_options=options)
File "/home/<user>/.virtualenvs/selenium/lib64/python3.6/site-packages/selenium/webdriver/chrome/webdriver.py", line 69, in __init__
desired_capabilities=desired_capabilities)
File "/home/<user>/.virtualenvs/selenium/lib64/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 98, in __init__
self.start_session(desired_capabilities, browser_profile)
File "/home/<user>/.virtualenvs/selenium/lib64/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 188, in start_session
response = self.execute(Command.NEW_SESSION, parameters)
File "/home/<user>/.virtualenvs/selenium/lib64/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 256, in execute
self.error_handler.check_response(response)
File "/home/<user>/.virtualenvs/selenium/lib64/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown error: Chrome failed to start: exited abnormally
(Driver info: chromedriver=2.38.552522 (437e6fbedfa8762dec75e2c5b3ddb86763dc9dcb),platform=Linux 4.14.12-x86_64-linode92 x86_64)
终于找到了解决方案。男孩,这困扰我太久了。问题在缺少 PATH 目录之后:cron 中的/usr/bin、/usr/sbin。完整的 cron 现在看起来像这样:
SHELL=/bin/bash
PATH=/usr/local/bin/:/usr/bin:/usr/sbin
* * * * * cd /to/path && /to/path/.virtualenvs/selenium/bin/python /to/path/script.py -t arg1 arg2 > /to/path/log.txt 2>&1
对我有帮助的是以下步骤:
- 将"DISPLAY=:1"添加到我的 crontab
- 在 crontab 中设置正确的外壳(我使用"zsh"(
- 获取环境变量,因为 crontab 默认情况下不这样做
- 使用浏览器驱动程序的绝对路径
TLDR
-
对 crontab 所需的修改是:
SHELL=/bin/zsh 05 * * * * export DISPLAY=:<displayNumber> && source /home/<username>/.zshrc && cd <absoluteExecutableDirectory> && ./<pythonFile> >> log.log 2>&1
-
使用以下行初始化硒铬驱动程序:
driver = webdriver.Chrome(<absoluteDriverPath>,...)
将尖括号内的所有内容替换为各自的值。
1. 设置显示
要找出要添加到 crontab 的显示器,请使用: env | grep 'DISPLAY'
然后将这部分添加到您的 crontab 命令中:
export DISPLAY=:1
2. 设置外壳
如果您有非默认外壳*,请设置外壳。 使用两个命令之一找出外壳的位置
which bash which zsh
然后将 shell 设置为上一个命令的响应(在您的 crontab 中(:
SHELL=/bin/zsh
3.获取环境变量
将以下部分之一添加到您的 crontab 命令中,具体取决于您使用 bash 还是 zsh:
source /home/<username>/.zshrc
source /home/<username>/.bashrc
4. 为您的浏览器驱动程序使用绝对路径:
初始化驱动程序时,请使用以下行,其中指向硒铬驱动程序。
driver = webdriver.Chrome(<absoluteDriverPath>,options=options)
其他
>> log.log 2>&1
意味着所有输出都写入文件(这样可以更轻松地调试 crontabs(。
在 ubuntu 18.04 上,Python 3.6.9:
它在我的主工作站上,所以我总是有一个登录的 X 会话。
我的硒调用:
#!/usr/bin/python3
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
driver = webdriver.Firefox()
location = 'http://example.com'
driver.get(location)
我在 crontab 中放了什么:
33 14 * * * DISPLAY=:0 lxterminal --working-directory=/home/user/Documents/ -e /home/user/bin/get.stats.by.zip.py > /home/user/gbzp.log 2>&1
lxterminal是一个相对简单的终端程序,我倾向于使用它来做大多数终端的东西,而不是像gnome-terminal那样,安装apt-get。
- 打开终端并运行命令:
回声$DISPLAY
让这个命令的输出是::0
- 打开 crontab 进行编辑:
crontab -e
- 在 crontab 内,附加以下行:
DISPLAY=:0 ## If output of "echo $DISPLAY" is: ":1", then change the above line to: "DISPLAY=:1" (without quotes) ## if running the python file every 2 minutes: # If firefox is used for selenium automation: */2 * * * * export PATH=$PATH:path_to_python_executable_folder:geckodriver_folder_path_for_firefox; python path_to_your_python_script.py # If chrome is used for selenium automation: */2 * * * * export PATH=$PATH:path_to_python_executable_folder:chromedriver_folder_path; python path_to_your_python_script.py