【问题标题】:Python selenium child class opens a new browser window - how to prevent this?Python selenium 子类打开一个新的浏览器窗口 - 如何防止这种情况?
【发布时间】:2022-01-13 03:10:40
【问题描述】:

我正在尝试为我的 selenium 浏览器创建一个子类。这是我的代码:

class SeleniumDriver:
    """Class that represents a game."""
    def __init__(self):
        # start Tor browser
        self.profile_path = r'C:\Tor Browser2\Browser\TorBrowser\Data\Browser\profile.default'
        self.options = Options()
        self.options.binary_location = r'C:\Tor Browser2\Browser\firefox.exe'
        self.options.set_preference('profile', self.profile_path)
        self.service = Service('C:/Utility/BrowserDrivers/geckodriver/geckodriver.exe')
        self.driver = Firefox(service=self.service, options=self.options)

class Items(SeleniumDriver):
    def __init__(self):
        super().__init__()
    # More methods that do stuff....

当我初始化这两个类时,子类会启动一个新的浏览器窗口。如何使其附加到现有/父级初始化浏览器?我尝试将“self.driver = Firefox”分离到另一种方法,但随后子类抛出:

AttributeError: 'Item' object has no attribute 'driver'

【问题讨论】:

    标签: python selenium class inheritance parent-child


    【解决方案1】:

    有多种方法可以解决这个问题。

    但一般来说,你应该认为你真的需要继承吗?

    为什么不委托?

    如果您只想使用某个类启动的驱动程序,则将driver 作为参数添加到构造函数,甚至添加SeleniumDriver 作为参数。

    https://erikscode.space/index.php/2020/08/01/delegate-and-decorate-in-python-part-1-the-delegation-pattern/

    以驱动程序为参数

    class SeleniumDriver:
    
        driver = None
    
        def __init__(self):
            ...
            self.driver = Firefox(service=self.service, options=self.options)
    
    class Items:
    
        driver = None
    
        # parameterized constructor
        def __init__(self, driver):
            self.driver = driver
    
    ...
    seleniumDriver = SeleniumDriver()
    itemsObj = Items(seleniumDriver.driver)
    

    以 SeleniumDriver 作为参数

    class Items:
    
        seleniumDriver = None
    
        # parameterized constructor
        def __init__(self, seleniumDriver):
            self.seleniumDriver = seleniumDriver
    
    ...
    
    seleniumDriver = SeleniumDriver()
    itemsObj = Items(seleniumDriver)
    

    继续使用继承

    对于这种情况,我建议从构造函数中移出这一行

    self.driver = Firefox(service=self.service, options=self.options)
    

    到单独的start_driver 方法:

    class SeleniumDriver:
        
        def __init__(self):
            self.profile_path = r'C:\Tor Browser2\Browser\TorBrowser\Data\Browser\profile.default'
            self.options = Options()
            self.options.binary_location = r'C:\Tor Browser2\Browser\firefox.exe'
            self.options.set_preference('profile', self.profile_path)
            self.service = Service('C:/Utility/BrowserDrivers/geckodriver/geckodriver.exe')
    
        def start_driver(self):
            self.driver = Firefox(service=self.service, options=self.options)
    
    
    class Items(SeleniumDriver):
        def __init__(self):
            super().__init__()
    
        def with_driver(self, driver):
            self.driver = driver
    
    ...
    seleniumDriver = SeleniumDriver()
    seleniumDriver.start_driver()
    
    itemsObj = Items()
    itemsObj.with_driver(seleniumDriver.driver)
    

    或将驱动参数添加到构造函数:

    class Items(SeleniumDriver):
        def __init__(self, driver):
            super().__init__()
            self.driver = driver
    
    ...
    seleniumDriver = SeleniumDriver()
    seleniumDriver.start_driver()
    itemsObj = Items(seleniumDriver.driver) #make sure start_driver() already invoked on seleniumDriver
    

    【讨论】:

    • 非常感谢您提供如此详细的解释。我是 python 新手,之前没有听说过委托。但是,我想在我的情况下使用继承。当我尝试在您提供的使用继承建议中执行此操作时,Items 类中“self.driver = driver”中的“self”显示未解析引用“self”。
    • 对不起,没有在 ide 中运行这个。我会尝试运行这个代码并明天更新我的答案。我会 ping 你。
    • @RuslanAli-zade,我已经更新了答案。 def with_driver(self, driver) 应该代替 def with_driver(driver)
    • 感谢您的更新!它现在完美无缺。非常感谢您抽出宝贵时间提供帮助。
    • @RuslanAli-zade 如果它足够有用,您可以接受答案,请参阅meta.stackexchange.com/questions/5234/…
    猜你喜欢
    • 1970-01-01
    • 2013-06-23
    • 2021-03-03
    • 2020-05-11
    • 2015-06-12
    • 2011-02-18
    • 1970-01-01
    • 2013-01-09
    • 2023-03-25
    相关资源
    最近更新 更多