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就是用来做广告判断的工具函数,之前没有补全对应逻辑。
修复步骤
- 补全
_create_driver方法,基于已导入的get_webdriver_for实现浏览器驱动初始化,支持Firefox/Chrome两种浏览器配置。 - 补全
_load方法,实现启动后访问Google首页的逻辑。 - 补全
_get_ad_links方法,遍历搜索结果节点,过滤提取广告元素和对应跳转链接。 - 核对
__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
相关产品推荐
相关产品推荐

