【问题标题】:Getting Error in Selenium/Python - chromedriver executable needs to be in PATH在 Selenium/Python 中出错 - chromedriver 可执行文件需要在 PATH 中
【发布时间】:2020-10-13 09:01:24
【问题描述】:

首先,我知道这个问题在这里被问了很多。只是明确表示我已经阅读了大多数接受的答案并正确执行了所有步骤,但仍然收到问题中提到的这个错误。 下面是我的脚本以及所有其他信息

[我正在使用 selenium 和 chromedriver,试图在运行 ubuntu 20 的无头模式下将它与 chromium 浏览器一起使用]

cat test.py

from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.binary_location = '/usr/bin/chromium-browser'

driver = webdriver.Chrome(options=options, executable_path='/usr/local/bin/chromedriver')
driver.get("https://www.google.com")
print(driver.title)
print ("Headless Chrome Initialized")
driver.quit()

python3 test.py

Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/selenium/webdriver/common/service.py", line 72, in start                                           self.process = subprocess.Popen(cmd, env=self.env,
  File "/usr/lib/python3.8/subprocess.py", line 854, in __init__           self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.8/subprocess.py", line 1702, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)       FileNotFoundError: [Errno 2] No such file or directory: '/usr/local/bin/chromedriver'
                                                                       During handling of the above exception, another exception occurred:    
Traceback (most recent call last):
  File "test.py", line 9, in <module>
    driver = webdriver.Chrome(options=options, executable_path='/usr/local/bin/chromedriver')
  File "/usr/local/lib/python3.8/dist-packages/selenium/webdriver/chrome/webdriver.py", line 73, in __init__
    self.service.start()
  File "/usr/local/lib/python3.8/dist-packages/selenium/webdriver/common/service.py", line 81, in start
    raise WebDriverException(
selenium.common.exceptions.WebDriverException: Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home

我遵循了哪些步骤

sudo apt install chromium-browser
python3 -m pip install selenium
wget https://chromedriver.storage.googleapis.com/83.0.4103.39/chromedriver_linux64.zip
unzip chromedriver*
chmod +x chromedriver
sudo mv chromedriver /usr/local/bin/
sudo chown root:root /usr/local/bin/chromedriver
sudo chmod 0755 /usr/local/bin/chromedriver

一起验证一切

╭─[localhost] as xd003 in ~
╰─➤ lsb_release -a | grep Description && \
apt -qq list python3 && \
apt -qq list chromium-browser && \
which chromedriver && \
which chromium-browser && \
echo $PATH

No LSB modules are available.
Description:    Ubuntu 20.04 LTS
python3/focal,now 3.8.2-0ubuntu2 arm64 [installed]
chromium-browser/focal-updates,now 81.0.4044.129-0ubuntu0.20.04.1 arm64 [installed]
/usr/local/bin/chromedriver
/usr/bin/chromium-browser
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

一切看起来都不错,有人可以建议我做错了什么吗?

我在本地运行的 Ubuntu20 是我在我的 android 设备上使用的 Ubuntu Proot

【问题讨论】:

  • 我已经在那里阅读了接受的答案,唯一不同的是这一步 - export PATH=$PATH:/path/to/directory/of/executable/downloaded/in/previous/step ...而不是这个我做了 sudo mv geckodriver /usr/local/bin/ 虽然理想情况下这应该绝对有效
  • 我没有意识到你明确地将/usr/local/bin/geckodriver 路径作为参数,我的错。
  • 我看到你做了一个chmod +x,你确定是同一个用户在运行 Python 脚本吗?
  • @Arount 是的,我是唯一的用户

标签: python python-3.x selenium selenium-webdriver selenium-chromedriver


【解决方案1】:

经过几天的解决,我终于能够修复这个错误。

正如我所提到的,我正在 Android 设备上运行 Prooted Ubuntu 20。现在官方 chrome webdriver 似乎不支持 linux 内核架构为 aarch64 - https://chromedriver.chromium.org

要解决此问题,只需下载为 arm64 变体编译的 chromedriver。您始终可以从此处获取最新版本 - https://github.com/electron/electron/releases

简而言之,其他一切都很完美,只需将 wget 链接替换为 -https://github.com/electron/electron/releases/download/v8.3.4/chromedriver-v8.3.4-linux-arm64.zip

PS / 也许如果错误类似于 - 不支持 linux 内核架构,修复它会容易得多,但没关系。

【讨论】:

    【解决方案2】:
    1. chromedriver 我总是传递给构造函数
    2. 如果找不到 PATH 则会发生错误(请参阅下面的示例,其中我故意传递了错误的参数)
    3. 此驱动程序不适用于铬,仅适用于铬。因此有理由将驱动程序与/usr/bin dir 分开
    import time, os, datetime, json, requests, re, subprocess
    from distutils.version import StrictVersion
    from pathlib import Path
    import xmlplain
    import selenium
    from selenium import webdriver
    
    def get_release(v):
        r = re.compile(f'^(83\.[0-9]+\.[0-9]+).*linux.*$')
        maxrel = "0.0.0"
        pos = 0
        for i, rel in enumerate(v):
            if r.match(rel) is not None and StrictVersion(r.split(rel)[1]) > StrictVersion(maxrel): 
                maxrel = r.split(rel)[1]
                pos = i
    
        return v[pos]
    
    def cmd(cmd:str, assertfail=True) :
        up = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
        str = [l.rstrip().decode() for l in up.stdout]
        exitcode = up.wait()
        if assertfail: assert exitcode == 0, f"[{exitcode}] {cmd} {str}"
        return exitcode,  str
    
    
    if __name__ == '__main__':
        # os.environ["DISPLAY"] = ":0.0"
    
        # find latest driver available
        resp = requests.get("https://chromedriver.storage.googleapis.com")
        raw = xmlplain.xml_to_obj(resp.content, strip_space=True, fold_dict=False)
        v = get_release([e["Contents"][0]["Key"] for e in raw["ListBucketResult"] if "Contents" in e.keys()])
        # download if required
        if not Path.cwd().joinpath(v.split("/")[0]).is_dir():
            cmd(f"mkdir {v.split('/')[0]}")
            cmd(f"wget https://chromedriver.storage.googleapis.com/{v} -O {v}")
            cmd(f"unzip {v} -d {v.split('/')[0]}/")
        # hit a webpage
        try:
            driver = webdriver.Chrome(f"unknown/chromedriver")  # Optional argument, if not specified will search path.
        except selenium.common.exceptions.WebDriverException as e:
            print(e)
        options = webdriver.ChromeOptions()
        options.add_argument('--no-sandbox')
        options.add_argument('--headless')
        options.add_argument('--disable-dev-shm-usage')
        options.binary_location = '/usr/bin/chromium-browser'
        options.binary_location = '/usr/bin/google-chrome'
        driver = webdriver.Chrome(f"{v.split('/')[0]}/chromedriver", options=options)  # Optional argument, if not specified will search path.
        driver.get('https://www.google.com')
        print(driver.title)
        print ("Headless Chrome Initialized")
        driver.quit()
    

    输出:

    Message: 'chromedriver' executable needs to be in PATH. Please see https://sites.google.com/a/chromium.org/chromedriver/home
    
    Google
    Headless Chrome Initialized
    

    【讨论】:

    • 您说 chromedriver 不适用于 chromium,但我在这里看到很多人在这里询问它,并且许多人可能也在使用它。这里有 2 个这样的问题,其中有不错投票的答案表明我们可以使用 chromium 浏览器而不是 chrome - stackoverflow.com/questions/5731953/… stackoverflow.com/questions/24999318/…
    • 另请阅读我的解决方案,我认为 chromedriver 错误地输出了它应该正确地说它需要在路径中 - 不支持 Linux 内核架构。无论如何感谢您的意见
    • 你的观点都是正确的。当 chromedriver 与浏览器不兼容时产生的错误通常不会这么说。当我将此 chromedriver 与 chromium 一起使用时,我收到 DevToolsActivePort 错误,但不是兼容性错误,也不是 PATH 错误。还需要为架构编译驱动程序——树莓派需要为 ARM 处理器编译的驱动程序。你也注意到了这一点。恕我直言,开始使用 chrome,然后转移到 chromium,因为知道有工作可以找到适当构建的驱动程序。
    • 是的,如果可能的话,我会使用 chrome,但在我正在运行的有源 ubuntu20 中,无法以任何方式安装 chrome。无论如何,最终通过使用 arm64 chromedriver 和 chromium 解决了这个问题。对于你提到的那个 devtools 错误,我几天前就遇到了,我通过添加这两行来解决它
    • options.add_argument('--disable-dev-shm-usage') options.add_argument("--remote-debugging-port=9222")
    猜你喜欢
    • 2022-01-16
    • 2019-11-11
    • 1970-01-01
    • 2018-12-14
    • 2017-03-26
    • 2021-08-19
    • 1970-01-01
    • 2020-11-04
    • 2017-12-08
    相关资源
    最近更新 更多