You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python新手修改Robot Framework SeleniumLibrary遇多错误求助

Hey there! Let's walk through the issues in your code step by step—there are a few common pitfalls here that are causing those errors. Let's fix them one by one:

1. Typos and Path Handling Mistakes

  • You have a typo in DEFAULT_BROWSR—it should be DEFAULT_BROWSER (missing an 'E'). This would trigger a NameError when trying to use the default browser.
  • Your DRIVERS_PATH uses backslashes (\) which act as escape characters in Python. Instead, let os.path.join handle path separators automatically, and skip unnecessary trailing slashes:
    DRIVERS_PATH = os.path.join(os.getcwd(), "drivers")
    
  • In _get_driver_path, the line return getattr(self, driver_path) is incorrect. driver_path is a string pointing to your driver executable, not an attribute of your class. Just return driver_path directly.

2. Undefined Helper Functions

You're using is_falsy() and is_truthy() which aren't built-in Python functions, and you haven't defined them in your code. Replace these with standard boolean checks:

  • Swap if is_falsy(remote_url): with if not remote_url:
  • Swap if is_truthy(remote): with if remote:

3. Missing Attributes and Deprecated Methods

  • In _make_ff, you reference self._geckodriver_log_config but never define this attribute. Either add it to your __init__ method (e.g., self._geckodriver_log_config = {}) or remove the parameter entirely if you don't need log configuration.
  • The set_headless() method for browser options is deprecated in newer Selenium versions. Use argument flags instead:
    • For Firefox: options.add_argument("--headless")
    • For Chrome: options.add_argument("--headless=new") (the new flag is recommended for modern Chrome releases)

4. Incorrect Driver Path Passing

You never pass the driver executable path to webdriver.Chrome or webdriver.Firefox, so Selenium can't locate your drivers. We'll adjust the code to pass this path through all driver creation functions.

5. Confusing Browser Binary vs Driver Path

Your line desired_capabilities = {"chrome.binary": driver_path} mixes up the Chrome browser binary path with the chromedriver executable path. The driver path is passed via executable_path, while chrome.binary is only needed if you're using a non-default Chrome installation. We'll remove this hardcoded capability unless you specifically need it.


Fixed Full Code

Here's the revised code with all these fixes applied:

import os
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

DEFAULT_BROWSER = 'chrome'  # Fixed typo
DRIVERS_PATH = os.path.join(os.getcwd(), "drivers")  # Fixed path handling

BROWSER_NAMES = {
    'ff': "_make_ff",
    'firefox': "_make_ff",
    'headlessfirefox': '_make_headless_ff',
    'gc': "_make_chrome",
    'googlechrome': "_make_chrome",
    'headlesschrome': '_make_headless_chrome',
    'chrome': "_make_chrome",
}

BROWSER_PATHS = {
    '_make_ff': os.path.join("geckodriver-win32", "geckodriver.exe"),
    '_make_headless_ff': os.path.join("geckodriver-win32", "geckodriver.exe"),
    '_make_chrome': os.path.join("chromedriver_win32", "chromedriver.exe"),
    '_make_headless_chrome': os.path.join("chromedriver_win32", "chromedriver.exe"),
}

class driver(object):
    """docstring for driver"""
    def __init__(self):
        self.driver = None
        self.driver_path = None
        self.timeout = 20
        self.implicit_wait = 5
        self._geckodriver_log_config = {}  # Added missing attribute

    def create(self, browser_name=DEFAULT_BROWSER):
        return self._make_driver(browser_name)

    def _make_driver(self, browser_name, desired_capabilities=None, profile_dir=None, remote=None):
        creation_func = self._get_driver_creation_function(browser_name)
        driver_path = self._get_driver_path(browser_name)
        driver = creation_func(remote, desired_capabilities, profile_dir, driver_path=driver_path)
        driver.set_script_timeout(self.timeout)
        driver.implicitly_wait(self.implicit_wait)
        return driver

    """ Return browser function name """
    def _get_driver_creation_function(self, browser_name):
        try:
            func_name = BROWSER_NAMES[browser_name.lower()]  # Added case insensitivity
        except KeyError:
            raise ValueError(f"{browser_name} is not a supported browser.")
        return getattr(self, func_name)

    """ Return browser driver path """
    def _get_driver_path(self, browser_name):
        try:
            func_name = self._get_driver_creation_function(browser_name)
            driver_path = os.path.join(DRIVERS_PATH, BROWSER_PATHS[func_name])
        except KeyError:
            raise ValueError(f"{browser_name} is not a supported browser.")
        return driver_path  # Fixed: return path directly

    """ Used inside driver creation functions """
    def _generic_make_driver(self, webdriver_type, desired_cap_type, remote_url, desired_caps, driver_path, options=None):
        if not remote_url:
            if options is None:
                driver = webdriver_type(executable_path=driver_path)
            else:
                driver = webdriver_type(executable_path=driver_path, options=options)
        else:
            driver = self._create_remote_web_driver(desired_cap_type, remote_url, desired_caps, options=options)
        return driver

    def _create_remote_web_driver(self, capabilities_type, remote_url, desired_capabilities=None, profile=None, options=None):
        desired_capabilities_object = capabilities_type.copy()
        if not isinstance(desired_capabilities, dict):
            desired_capabilities = self._parse_capabilities_string(desired_capabilities)
        desired_capabilities_object.update(desired_capabilities or {})
        return webdriver.Remote(desired_capabilities=desired_capabilities_object, 
                                command_executor=str(remote_url), 
                                browser_profile=profile, 
                                options=options)

    def _make_ff(self, remote, desired_capabilities, profile_dir, driver_path, options=None):
        if not profile_dir:
            profile = webdriver.FirefoxProfile()
        else:
            profile = webdriver.FirefoxProfile(profile_dir)
        if remote:
            driver = self._create_remote_web_driver(webdriver.DesiredCapabilities.FIREFOX, remote, desired_capabilities, profile, options=options)
        else:
            driver = webdriver.Firefox(firefox_profile=profile, options=options, executable_path=driver_path, **self._geckodriver_log_config)
        return driver

    def _make_headless_ff(self, remote, desired_capabilities, profile_dir, driver_path):
        options = webdriver.FirefoxOptions()
        options.add_argument("--headless")  # Replaced deprecated method
        return self._make_ff(remote, desired_capabilities, profile_dir, driver_path, options=options)

    def _make_chrome(self, remote, desired_capabilities, profile_dir, driver_path, options=None):
        return self._generic_make_driver(
            webdriver.Chrome, webdriver.DesiredCapabilities.CHROME,
            remote, desired_capabilities, driver_path, options=options)

    def _make_headless_chrome(self, remote, desired_capabilities, profile_dir, driver_path):
        options = webdriver.ChromeOptions()
        options.add_argument("--headless=new")  # Replaced deprecated method
        return self._make_chrome(remote, desired_capabilities, profile_dir, driver_path, options)

    # Added missing method called in remote driver creation
    def _parse_capabilities_string(self, capabilities_str):
        # Implement custom parsing logic here if needed; returns empty dict for now
        return {}

Key Extra Improvements:

  • Added .lower() to browser_name in _get_driver_creation_function for case-insensitive browser name handling (e.g., "Chrome" vs "chrome")
  • Added the missing _parse_capabilities_string method (it was called but never defined)
  • Passed driver_path as a parameter to all driver creation functions so they can use it with executable_path
  • Fixed Firefox driver creation to include the executable path

Now when you run driver().create(), it should correctly locate your chromedriver executable and launch Chrome as expected.

内容的提问来源于stack exchange,提问作者deyaamuhammad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:08:40