selenium _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0

本文详细解析了在使用Selenium WebDriver进行自动化测试时,close()与quit()方法的区别。close()仅关闭当前窗口,而quit()则退出整个WebDriver会话,释放所有资源。错误示例展示了使用close()后可能出现的异常,强调了正确使用quit()的重要性。

在关闭driver时,如果用close,而不是用quit,会出现如下错误:

Exception ignored in: <bound method Popen.__del__ of <subprocess.Popen object at 0x0000027A6CAD1278>>
Traceback (most recent call last):
File "E:\python36\lib\subprocess.py", line 768, in __del__
self._internal_poll(_deadstate=_maxsize)
File "E:\python36\lib\subprocess.py", line 1035, in _internal_poll
if _WaitForSingleObject(self._handle, 0) == _WAIT_OBJECT_0:
OSError: [WinError 6] 句柄无效。

原因,close只关闭当前window,而quit才能退出整个driver,

 

转载于:https://www.cnblogs.com/xqnq2007/p/7929346.html

from django.contrib.auth.decorators import login_required from selenium import webdriver from selenium.webdriver.chrome.options import Options as ChromeOptions from selenium.webdriver.edge.options import Options as EdgeOptions from selenium.webdriver.firefox.options import Options as FirefoxOptions from selenium.webdriver.chrome.service import Service as ChromeService from selenium.webdriver.edge.service import Service as EdgeService from selenium.webdriver.firefox.service import Service as FirefoxService from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.action_chains import ActionChains from selenium.common.exceptions import TimeoutException, ElementClickInterceptedException import time class BrowserConfig: def __init__(self, browser_type='edge', headless=False): self.browser_type = browser_type.lower() self.headless = headless self.options = self._setup_options() self.driver_path = self._get_driver_path() def _setup_options(self): options = { 'chrome': ChromeOptions(), 'edge': EdgeOptions(), 'firefox': FirefoxOptions() } if self.browser_type not in options: raise ValueError(f"Unsupported browser: {self.browser_type}") if self.headless: if self.browser_type == 'chrome': self.options.add_argument('--headless=new') self.options.add_argument('--disable-gpu') elif self.browser_type == 'edge': self.options.add_argument('--headless=chrome') elif self.browser_type == 'firefox': self.options.add_argument('--headless') return options[self.browser_type] def _get_driver_path(self): driver_paths = { 'edge': r"C:\own\app\python_code\work\入职培训\打印点击\msedgedriver.exe" } return driver_paths.get(self.browser_type) def get_driver(self): if self.browser_type == 'chrome': return webdriver.Chrome(options=self.options) elif self.browser_type == 'edge': if not self.driver_path: raise ValueError("Edge driver path is required.") service = EdgeService(executable_path=self.driver_path) return webdriver.Edge(service=service, options=self.options) elif self.browser_type == 'firefox': return webdriver.Firefox(options=self.options) else: raise ValueError(f"Unsupported browser: {self.browser_type}") class ElementActions: def __init__(self, driver): self.driver = driver self.action = ActionChains(driver) def scroll_to_element(self, element): try: self.driver.execute_script("arguments[0].scrollIntoView({block: 'center'});", element) time.sleep(0.3) except Exception as e: print(f"滚动失败: {e}") def safe_click(self, element): try: element.click() except ElementClickInterceptedException: print("元素被遮挡,尝试使用 JavaScript 点击") self.driver.execute_script("arguments[0].click();", element) def wait_for_element(self, by, locator, timeout=10): return WebDriverWait(self.driver, timeout).until( EC.presence_of_element_located((by, locator))) class AutomationWorkflow: def __init__(self, browser_config, login_url="http://10.244.1.179:3000/"): self.browser_config = browser_config self.login_url = login_url self.driver = browser_config.get_driver() self.element_actions = ElementActions(self.driver) self.driver.get(self.login_url) # self.set_cl=Settings_handler(self.browser_config) print(f"Browser {self.browser_config.browser_type} started in " f"{'headless' if self.browser_config.headless else 'headed'} mode.") def login(self, email, password): try: email_input = self.element_actions.wait_for_element(By.NAME, 'email') email_input.send_keys(email) password_input = self.element_actions.wait_for_element(By.NAME, 'current-password') password_input.send_keys(password) login_button = self.driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]') login_button.click() time.sleep(1) return True except TimeoutException: print("登录失败,元素未加载或超时") return False except Exception as e: print(f"登录过程中发生错误: {str(e)}") return False def logout(self): try: user_button = self.element_actions.wait_for_element( By.XPATH, "//button[@aria-label='User Menu']") self.element_actions.safe_click(user_button) logout_button = self.driver.find_element( By.XPATH, "//div[text()='サインアウト']") self.element_actions.safe_click(logout_button) print("登出成功") except Exception as e: print(f"登出过程中发生错误: {str(e)}") def click_all_clickable_elements(self): try: elements_locator = (By.CSS_SELECTOR, 'button, a, input[type="button"], input[type="submit"], ' 'div[role="button"], div[onclick], [role="menuitem"], ' '[role="option"], [data-testid*="button"], [class*="btn"], ' '[class*="clickable"]') elements = WebDriverWait(self.driver, 10).until( EC.presence_of_all_elements_located(elements_locator)) count = len(elements) print(f"初始找到 {count} 个可能可点击的元素") original_window = self.driver.current_window_handle original_url = self.driver.current_url for index in range(count): try: elements = self.driver.find_elements(*elements_locator) if index >= len(elements): print(f"元素列表已变化,跳过索引 {index}") continue element = elements[index] self.element_actions.scroll_to_element(element) if element.is_displayed() and element.is_enabled(): element.click() print(f"已点击元素 {index + 1}/{count}") time.sleep(0.5) try: alert = WebDriverWait(self.driver, 3).until( EC.alert_is_present()) print("检测到弹窗,正在处理...") alert.accept() except TimeoutException: print("无弹窗") time.sleep(0.2) current_windows = self.driver.window_handles if len(current_windows) > 1: for window in current_windows: if window != original_window: self.driver.switch_to.window(window) self.driver.close() self.driver.switch_to.window(original_window) else: if self.driver.current_url != original_url: self.driver.back() WebDriverWait(self.driver, 10).until( EC.presence_of_all_elements_located(elements_locator)) except Exception as e: print(f"点击元素 {index + 1} 时出错: {str(e)}") continue except Exception as e: print(f"处理可点击元素时出错: {str(e)}") def handle_input_fields(self, test_value="12"): try: input_elements = self.driver.find_elements(By.CSS_SELECTOR, 'input[type="text"], input[type="email"], input[type="number"], ' 'input[type="password"], input[type="tel"], input[type="url"], ' 'textarea, [role="textbox"], [contenteditable="true"]') print(f"找到 {len(input_elements)} 个输入框") original_window = self.driver.current_window_handle original_url = self.driver.current_url for index, element in enumerate(input_elements): try: self.element_actions.scroll_to_element(element) element.clear() element.send_keys(test_value) print(f"已在输入框 {index + 1} 中输入测试值") form = element.find_element(By.XPATH, "./ancestor::form[1]") if form: submit_buttons = form.find_elements(By.CSS_SELECTOR, 'button[type="submit"], input[type="submit"]') if submit_buttons: submit_buttons[0].click() print(f"已提交输入框 {index + 1} 所在的表单") time.sleep(1) current_windows = self.driver.window_handles if len(current_windows) > 1: for window in current_windows: if window != original_window: self.driver.switch_to.window(window) self.driver.close() self.driver.switch_to.window(original_window) else: if self.driver.current_url != original_url: self.driver.back() time.sleep(2) except Exception as e: print(f"处理输入框 {index + 1} 时出错: {str(e)}") except Exception as e: print(f"处理输入框时出错: {str(e)}") def run_automation(self, email, password,login_required=True): if login_required and self.login_url: if not self.login(email, password): print("登陆失败") return print("开始自动化操作...") self.click_all_clickable_elements() self.handle_input_fields() time.sleep(2) # self.set_cl.click_settings_button() if login_required and self.login_url:#判断是否要登出 self.logout() print("自动化操作完成") time.sleep(3) self.driver.quit() if __name__ == "__main__": login_url = "http://10.244.1.179:3000/" email = "shengkai.qu@brother-bsh.com.cn" password = "q123456.+" login_required=True browser_config = BrowserConfig(browser_type='edge', headless=False) automation_workflow = AutomationWorkflow( browser_config=browser_config, login_url=login_url) automation_workflow.run_automation(email, password,login_required) 对输入框的处理为人工输入
08-19
你提供的代码是一个完整的 Selenium 自动化测试脚本,使用 Python 编写,主要功能包括: - 浏览器初始化配置(支持 Chrome、Edge、Firefox,支持无头模式) - 登录操作 - 点击所有可点击元素 - 自动填写输入框 - 自动提交表单 - 异常处理(弹窗、新窗口、遮挡点击) - 自动登出 - 整体自动化流程控制 你的问题是: > 对输入框的处理为人工输入 这表示你希望将原本自动填写输入框的部分改为由人工手动输入,而不是由脚本自动发送文本。我们可以通过修改 `handle_input_fields` 方法实现这个目的。 --- ### ✅ 解决方案 我们可以将 `handle_input_fields` 方法中的 `element.send_keys(test_value)` 这一行注释掉或删除,并加入提示信息,让用户手动输入数据。 ### ✅ 修改后的代码如下: ```python def handle_input_fields(self, test_value="12"): try: input_elements = self.driver.find_elements(By.CSS_SELECTOR, 'input[type="text"], input[type="email"], input[type="number"], ' 'input[type="password"], input[type="tel"], input[type="url"], ' 'textarea, [role="textbox"], [contenteditable="true"]') print(f"找到 {len(input_elements)} 个输入框") original_window = self.driver.current_window_handle original_url = self.driver.current_url for index, element in enumerate(input_elements): try: self.element_actions.scroll_to_element(element) # element.clear() # 可选:是否清空原有内容 print(f"请手动在输入框 {index + 1} 中输入内容。") time.sleep(5) # 给用户5秒时间输入 # 可选:获取用户输入的值 entered_value = element.get_attribute('value') print(f"您在输入框 {index + 1} 中输入的内容为: {entered_value}") form = element.find_element(By.XPATH, "./ancestor::form[1]") if form: submit_buttons = form.find_elements(By.CSS_SELECTOR, 'button[type="submit"], input[type="submit"]') if submit_buttons: submit_buttons[0].click() print(f"已提交输入框 {index + 1} 所在的表单") time.sleep(1) current_windows = self.driver.window_handles if len(current_windows) > 1: for window in current_windows: if window != original_window: self.driver.switch_to.window(window) self.driver.close() self.driver.switch_to.window(original_window) else: if self.driver.current_url != original_url: self.driver.back() time.sleep(2) except Exception as e: print(f"处理输入框 {index + 1} 时出错: {str(e)}") except Exception as e: print(f"处理输入框时出错: {str(e)}") ``` ### ✅ 修改说明 - 原本的 `element.send_keys(test_value)` 被移除,改为提示用户手动输入。 - 增加了 `time.sleep(5)` 给用户时间输入。 - 使用 `element.get_attribute('value')` 获取用户输入内容并打印出来(可选)。 --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值