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

Python Selenium报错:SearchController对象无create_driver属性

问题根因

报错直接原因是SearchController类里缺失了多个被调用但未实现的方法,叠加方法名书写笔误:

  • 初始化方法__init__中调用了驱动创建方法,但类中根本没有编写该方法的实现。你贴出的代码里写的是调用self._create_driver(),但CLI报错栈显示实际运行的代码调用的是无前缀下划线的self.create_driver(),属于代码版本不一致+方法名笔误+方法缺失的叠加问题。你提前导入的webdriver_setup.get_webdriver_for本来就是用来生成浏览器驱动实例的,之前没有把这部分逻辑封装到对应方法里。
  • __init__中调用的self._load()方法未实现,该方法的预期作用是驱动启动后跳转至Google搜索首页。
  • search_for_ads中调用的self._get_ad_links()方法未实现,该方法的预期作用是提取搜索结果页的广告链接,你提前导入的contains_ad就是用来做广告判断的工具函数,之前没有补全对应逻辑。
修复步骤
  1. 补全_create_driver方法,基于已导入的get_webdriver_for实现浏览器驱动初始化,支持Firefox/Chrome两种浏览器配置。
  2. 补全_load方法,实现启动后访问Google首页的逻辑。
  3. 补全_get_ad_links方法,遍历搜索结果节点,过滤提取广告元素和对应跳转链接。
  4. 核对__init__中的方法调用名和定义的方法名完全一致,避免漏写私有方法下划线前缀的笔误。

修复后的完整可运行代码如下:

from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import FirefoxProfile, ChromeOptions
from selenium.common.exceptions import TimeoutException, NoSuchElementException
from time import sleep
from webdriver_setup import get_webdriver_for
from config import logger
from translations import contains_ad


class SearchController:

    URL = "https://www.google.com"
    SEARCH_INPUT = (By.NAME, "q")

    def __init__(self, query, browser="firefox", ad_visit_time=4):

        self._search_query = query
        self._ad_visit_time = ad_visit_time

        self._driver = self._create_driver(browser.lower())
        self._load()

    def _create_driver(self, browser):
        """初始化对应浏览器的驱动实例"""
        if browser == "firefox":
            profile = FirefoxProfile()
            # 可按需添加Firefox自定义配置,比如禁用通知、设置无头模式等
            driver = get_webdriver_for("firefox", firefox_profile=profile)
        elif browser == "chrome":
            opts = ChromeOptions()
            # 可按需添加Chrome启动参数
            driver = get_webdriver_for("chrome", options=opts)
        else:
            raise ValueError(f"暂不支持浏览器类型: {browser}")
        driver.maximize_window()
        return driver

    def _load(self):
        """加载搜索首页"""
        self._driver.get(self.URL)

    def _get_ad_links(self):
        """提取搜索结果页的所有广告链接"""
        ad_links = []
        # 遍历所有搜索结果节点
        result_nodes = self._driver.find_elements(By.XPATH, "//div[@class='g'] | //div[@data-text-ad='1']")
        for node in result_nodes:
            try:
                link_el = node.find_element(By.TAG_NAME, "a")
                link_url = link_el.get_attribute("href")
                if link_url and contains_ad(link_url, node.text):
                    ad_links.append((link_el, link_url))
            except NoSuchElementException:
                continue
        return ad_links

    def search_for_ads(self):
        """
        :Start search for the given query and return ads if any
        :rtype: list
        :returns: List of (ad, ad_link) tuples
        """

        logger.info(f"Starting search for '{self._search_query}'")

        search_input_box = self._driver.find_element(*self.SEARCH_INPUT)
        search_input_box.send_keys(self._search_query, Keys.ENTER)

        ad_links = []

        try:
            wait = WebDriverWait(self._driver, timeout=10)
            results_loaded = wait.until(EC.presence_of_element_located((By.ID, "result-stats")))

            if results_loaded:
                logger.info("Getting ad links...")
                ad_links = self._get_ad_links()

        except TimeoutException:
            logger.error("Timed out waiting for results!")
            self.end_search()

        return ad_links

    def click_ads(self, ads):
        """
        :Click ads found
        :type ads: list
        :param ads: List of (ad, ad_link) tuples
        """

        # store the ID of the original window
        original_window_handle = self._driver.current_window_handle

        for ad in ads:
            ad_link_element = ad[0]
            ad_link = ad[1]
            logger.info(f"Clicking {ad_link}...")

            # open link in a different tab
            ad_link_element.send_keys(Keys.CONTROL + Keys.RETURN)

            for window_handle in self._driver.window_handles:
                if window_handle != original_window_handle:
                    self._driver.switch_to.window(window_handle)
                    sleep(self._ad_visit_time)
                    self._driver.close()
                    break

            # go back to original window
            self._driver.switch_to.window(original_window_handle)
            sleep(1)

            # scroll the page to avoid elements remain outside of the view
            self._driver.execute_script("arguments[0].scrollIntoView(true);", ad_link_element)

    def end_search(self):
        """Close the browser"""

        self._driver.quit()

注意事项

运行前确认本地已经安装了对应版本的Firefox浏览器,webdriver_setup库会自动下载匹配版本的驱动文件,不需要手动配置webdriver路径。如果需要自定义浏览器启动参数,可以直接在_create_driver方法里添加对应配置即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 09:06:18