Python Selenium:如何在不同函数间共享WebDriver实例?
如何在独立函数中共享Selenium WebDriver实例?
我把Selenium操作拆成了两个独立函数:goToUrl_Se负责打开URL,parse_data负责抓取数据,但parse_data无法调用goToUrl_Se里的局部变量driver。想知道这种拆分是否合理,以及如何在第二个函数中使用WebDriver实例。
原代码:
import pandas as pd from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By #reading from csv file url-s def readCSV(path_csv): df=pd.read_csv(path_csv) return df fileCSV=readCSV(r'C:\Users\Admin\Downloads\urls.csv') length_of_column_urls=fileCSV['linkamazon'].last_valid_index() #going to urls 1-by-1 def goToUrl_Se(): for i in range(0, length_of_column_urls + 1): xUrl = fileCSV.iloc[i, 1] print(xUrl,i) # going to url(a,amazn) via Selenium WebDriver chrome_options = Options() chrome_options.headless = False chrome_options.add_argument("start-maximized") # options.add_experimental_option("detach", True) chrome_options.add_argument("--no-sandbox") chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) chrome_options.add_experimental_option('excludeSwitches', ['enable-logging']) chrome_options.add_experimental_option('useAutomationExtension', False) chrome_options.add_argument('--disable-blink-features=AutomationControlled') webdriver_service = Service(r'C:\pythonPro\w_crawl\AmznScrpBot\chromedriver.exe') driver = webdriver.Chrome(service=webdriver_service, options=chrome_options) driver.get(xUrl) driver.quit() #fetch-parse the data from url page def parse_data(): x_title=driver.find_element(By.XPATH,'//*[@id="search"]/div[1]/div[1]/div/span[3]/div[2]/div[2]/div/div/div/div/div/div[2]/div/div/div[1]/h2/a/span') goToUrl_Se()
拆分操作的合理性
拆分Selenium的导航和数据解析操作是合理的,能让代码职责更单一,提升可读性和后续维护性,只要正确处理WebDriver实例的共享即可。
解决方案
方案1:将WebDriver作为参数传递(最直接)
把driver作为参数传给parse_data函数,同时优化原代码中每次循环创建新driver的问题(这会打开大量浏览器窗口,效率极低),将driver初始化移到循环外部:
修改后的代码:
import pandas as pd from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By def readCSV(path_csv): df = pd.read_csv(path_csv) return df fileCSV = readCSV(r'C:\Users\Admin\Downloads\urls.csv') # 更简洁的获取有效行数方式 valid_urls = fileCSV['linkamazon'].dropna() def goToUrl_Se(): # 初始化driver(只做一次) chrome_options = Options() chrome_options.headless = False chrome_options.add_argument("start-maximized") chrome_options.add_argument("--no-sandbox") chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) chrome_options.add_experimental_option('excludeSwitches', ['enable-logging']) chrome_options.add_experimental_option('useAutomationExtension', False) chrome_options.add_argument('--disable-blink-features=AutomationControlled') webdriver_service = Service(r'C:\pythonPro\w_crawl\AmznScrpBot\chromedriver.exe') driver = webdriver.Chrome(service=webdriver_service, options=chrome_options) for idx, xUrl in enumerate(valid_urls): print(xUrl, idx) driver.get(xUrl) # 调用解析函数,传入driver parse_data(driver) driver.quit() def parse_data(driver): # 显式等待元素加载,避免直接查找报错 wait = WebDriverWait(driver, 10) x_title = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="search"]/div[1]/div[1]/div/span[3]/div[2]/div[2]/div/div/div/div/div/div[2]/div/div/div[1]/h2/a/span'))) print(x_title.text) goToUrl_Se()
方案2:使用类封装(更优雅,适合复杂场景)
把WebDriver实例和相关操作封装到类中,类的所有方法都能直接访问实例属性self.driver,代码结构更清晰:
修改后的代码:
import pandas as pd from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By class AmazonScraper: def __init__(self, csv_path, driver_path): self.df = pd.read_csv(csv_path) self.valid_urls = self.df['linkamazon'].dropna() self.driver_path = driver_path self.driver = None def init_driver(self): chrome_options = Options() chrome_options.headless = False chrome_options.add_argument("start-maximized") chrome_options.add_argument("--no-sandbox") chrome_options.add_experimental_option("excludeSwitches", ["enable-automation"]) chrome_options.add_experimental_option('excludeSwitches', ['enable-logging']) chrome_options.add_experimental_option('useAutomationExtension', False) chrome_options.add_argument('--disable-blink-features=AutomationControlled') webdriver_service = Service(self.driver_path) self.driver = webdriver.Chrome(service=webdriver_service, options=chrome_options) def parse_data(self): wait = WebDriverWait(self.driver, 10) x_title = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="search"]/div[1]/div[1]/div/span[3]/div[2]/div[2]/div/div/div/div/div/div[2]/div/div/div[1]/h2/a/span'))) print(x_title.text) def scrape(self): self.init_driver() for idx, xUrl in enumerate(self.valid_urls): print(xUrl, idx) self.driver.get(xUrl) self.parse_data() self.driver.quit() # 实例化并运行 scraper = AmazonScraper( csv_path=r'C:\Users\Admin\Downloads\urls.csv', driver_path=r'C:\pythonPro\w_crawl\AmznScrpBot\chromedriver.exe' ) scraper.scrape()
额外提示
- 原代码中直接使用
find_element容易遇到元素未加载完成的报错,建议始终使用显式等待(WebDriverWait)来确保元素存在后再操作。 - 获取有效URL时,用
dropna()比last_valid_index更可靠,能自动过滤空值。
内容的提问来源于stack exchange,提问作者xlmaster
相关产品推荐
相关产品推荐

