活动介绍

element=WebDriverWait(driver,10).until(lambda x: x.find_element_by_class_name('service'))解析代码

时间: 2025-08-30 19:11:35 AIGC 浏览: 10
<think>好的,我现在要解析用户提供的Python Selenium代码片段,理解其功能和用法,特别是涉及WebDriverWait、until方法和lambda表达式结合find_element_by_class_name的部分。首先,我需要回忆一下Selenium的相关知识,尤其是显式等待的机制。 根据用户提供的引用内容,引用[3]提到WebDriverWait会等待直到某个条件成立,每隔一段时间检查一次,直到超时。而until方法接收一个可调用对象,通常是expected_conditions或者lambda表达式。用户代码中使用的是lambda表达式,里面调用了driver.execute_script来检查document.readyState是否为complete,这可能是在等待页面加载完成。 接下来,用户的问题是关于find_element_by_class_name的,但提供的示例代码中并没有直接使用这个方法,而是用了execute_script来检查页面状态。不过,结合引用[2]中的说明,find_element_by_*方法底层都是调用find_element(By.CSS_SELECTOR, ...),但这里可能用户想了解的是如何在等待后定位元素。 可能用户给的代码示例中,在等待页面加载完成后,使用了find_element_by_id,但想了解的是如果换成class_name的情况。例如,等待某个元素通过class_name出现后再进行操作。这时候需要结合WebDriverWait和expected_conditions,比如EC.presence_of_element_located((By.CLASS_NAME, "classname"))。 另外,引用[3]中的示例展示了如何使用WebDriverWait和EC来等待元素出现,其中By.ID被使用,但换成By.CLASS_NAME即可适用于class名称的情况。而用户提到的lambda表达式可能是一种自定义的等待条件,比如检查元素是否存在,或者元素的某个属性是否符合预期。 现在需要将代码中的execute_script部分和元素定位部分分开分析。首先,wait_for_page_to_load函数通过检查document.readyState来确保页面整体加载完成。随后,在页面加载完成后,再查找元素并进行操作。然而,有时候页面加载完成并不代表所有动态元素都已加载,这时候可能需要显式等待特定元素的出现,比如通过class name查找。 例如,如果用户想等待某个具有特定class的元素出现,应该使用WebDriverWait结合EC.presence_of_element_located,并传入By.CLASS_NAME作为定位方式。例如: element = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME, "myClass"))) 这样就会等待直到该class的元素出现为止,或者在超时后抛出异常。 总结来说,用户提供的代码示例中,通过执行JavaScript检查页面状态,确保页面加载完成后再查找元素。而如果要用到find_element_by_class_name,可能需要结合显式等待来确保元素的存在,尤其是在处理动态加载内容时。同时,理解lambda在until方法中的作用,允许自定义等待条件,如检查元素的某个属性或状态是否符合预期。</think>以下是对Python Selenium代码中`WebDriverWait`与`until`结合`lambda`及`find_element_by_class_name`功能的解析: ### 代码功能解析 1. **显式等待机制** 通过`WebDriverWait(driver, timeout)`设置最大等待时间,利用`until`方法持续检测条件是否满足(默认每0.5秒检测一次)。若超时未满足条件,则抛出异常[^3]。 2. **Lambda表达式的作用** `lambda driver: ...`定义了一个匿名函数,用于自定义等待条件。例如: ```python WebDriverWait(driver, 10).until(lambda d: d.find_element_by_class_name("myClass").is_displayed()) ``` 此处通过`find_element_by_class_name`定位元素,并检查该元素是否可见。若找到且可见,则继续执行后续操作[^2]。 3. **与`find_element_by_class_name`结合** - **直接定位**:`driver.find_element_by_class_name("class_name")`直接查找元素,但若元素未加载会立即报错。 - **结合显式等待**:通过`WebDriverWait`等待元素存在或可交互: ```python element = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, "myClass")) ) ``` 此方式更稳定,适用于动态加载内容[^3]。 ### 完整示例代码 ```python 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 driver = webdriver.Chrome() driver.get("https://example.com") # 方法1:使用lambda自定义等待条件 element = WebDriverWait(driver, 10).until( lambda d: d.find_element_by_class_name("myClass") ) # 方法2:使用expected_conditions显式等待 element = WebDriverWait(driver, 10).until( EC.visibility_of_element_located((By.CLASS_NAME, "myClass")) ) element.click() driver.quit() ``` ### 关键点总结 - **显式等待优势**:避免因元素未加载导致的`NoSuchElementException`,提升脚本健壮性。 - **Lambda灵活性**:允许自定义复杂条件(如元素属性、多个元素状态组合)。 - **性能优化**:通过合理设置超时时间,平衡等待效率与稳定性[^1][^3]。
阅读全文

相关推荐

from seleniumwire import webdriver import unittest from jiaoben.login.action.page_login import LoginPage from selenium.webdriver.chrome.options import Options class Login(unittest.TestCase): def setUp(self): options = Options() options.add_experimental_option("detach", True) # 关键配置 self.driver = webdriver.Chrome(options=options) self.driver.get("https://10.121.177.160") def test_login(self): print(f"开始登录") LoginPage(self.driver).input_key(user='admin', passwd='admin') # assert self.driver.title in "Chaoqiang G640 V7 10.121.176.137" print("登录成功") from selenium.webdriver.common.by import By from jiaoben.Method_Library.base_action import BaseAction class LoginPage(BaseAction): user = (By.ID,"userid") passwd = (By.ID,"password") title_list = (By.XPATH, '//*[@id="btn-login"]') def input_key(self, user, passwd): self.input(self.user, user) self.input(self.passwd, passwd) self.find_element(self.title_list).click() import time from pyexpat import features from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.common.alert import Alert class BaseAction: def __init__(self, driver): # 将传入的 driver 实例赋值给类的实例变量,供后续方法使用 self.driver = driver cookies = self.driver.get_cookies() #将cookies添加到浏览器当中,保持登录状态 for i in cookies: self.driver.add_cookie(i) #刷新页面,使添加的cookies生效 self.driver.refresh() def find_element(self, feature, timeout=10, poll=1): return WebDriverWait(self.driver, timeout, poll).until(lambda x: x.find_element(*feature)) def click(self, feature, timeout=10, poll=1): self.find_element(feature, timeout, poll).click() def input(self, feature, text, timeout=10, poll=1): self.find_element(feature, timeout, poll).send_keys(text) def clear_and_input(self, feature, text, timeout=10, poll=1): self.clear(feature, timeout, poll) self.find_element(feature, timeout, poll).send_keys(text) def clear(self, feature, timeout=10, poll=1): self.find_element(feature, timeout, poll).clear() def get_text(self, feature, timeout=10, poll=1): return self.find_element(feature, timeout, poll).text def get(self, feature, timeout=10, poll=1): return self.find_element(feature, timeout, poll) def switch_new_page(self): self.driver.switch_to.window(self.driver.window_handles[-1]) def switch_old_page(self): self.driver.switch_to.window(self.driver.window_handles[0]) def find_elements(self, feature, timeout=10, poll=1): return WebDriverWait(self.driver, timeout, poll).until(lambda x: x.find_elements(*feature)) def get_list(self, feature, timeout=10, poll=1): return self.find_elements(feature, timeout, poll) def move(self, feature, timeout=10, poll=1): webElement = self.get(feature, timeout, poll) self.driver.execute_script("arguments[0].scrollIntoView();",webElement) def move_to(self, feature, timeout=10, poll=1): webElement = self.find_element(feature, timeout, poll) ActionChains(self.driver).move_to_element(webElement).perform() def toset(self): alert = Alert(self.driver) alert.accept() # 点击确定/OK按钮 time.sleep(10) # 通用属性获取 def get_value(self, feature, attribute_name, timeout=10, poll=1): return self.find_element(feature, timeout, poll).get_attribute(attribute_name) 为什么会使得登录界面执行成功后一直停留在该页面

我在做遍历点击页面所有可点击的元素,现在遇到的问题是:导航栏a(有按钮a1 a2 a3 a4),导航栏b(b1 b2 b3 b4)再点击a切换后的页面中,a1a2 a3中的元素只会点击默认界面(a下的b没有被点击切换页面内容),a4中的b及对应的变化的内容全部被点击 我实现的逻辑是先获取所有可点击元素并将其分为导航和非导航, 优先点击非导航栏元素(a,b只是举例,并非具体名字) def click_all_clickable_elements(self, clicked_elements=None, depth=0, max_depth=20): if depth > max_depth: print("达到最大递归深度,停止点击") return if clicked_elements is None: clicked_elements = set() original_url = self.driver.current_url original_window = self.driver.current_window_handle elements = self.element_actions.get_all_clickable_elements() non_nav_elements = [] nav_elements = [] # 分类导航栏元素和非导航栏元素 for element in elements: try: element_id = self.element_actions.get_element_identifier(element) if element_id in clicked_elements: continue elements = self.element_actions.get_all_clickable_elements() if not element.is_displayed() or not element.is_enabled(): continue if self.is_inside_navigation_bar(element): nav_elements.append((element, element_id)) else: non_nav_elements.append((element, element_id)) except Exception as e: print(f"元素分类失败: {e}") continue # 优先点击非导航栏元素 for element, element_id in non_nav_elements: try: if self.element_actions.is_sensitive_element(element): continue before_state = self.element_actions.get_page_state() self.element_actions.scroll_to_element(element) self.element_actions.highlight_element(element) self.element_actions.safe_click(element) clicked_elements.add(element_id) print(f"点击非导航栏元素: {element_id}") if self.pass_handler(self.driver.current_url): continue self.element_actions.handle_alert() self.element_actions.handle_new_windows(original_window) WebDriverWait(self.driver, 10).until( lambda d: self.element_actions.compare_states(before_state, self.element_actions.get_page_state()) ) if self.driver.current_url != original_url: WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, 'body')) ) self.click_all_clickable_elements(clicked_elements, depth=depth + 1) self.driver.back() non_nav_elements = self.element_actions.get_all_clickable_elements() # 重新获取元素 WebDriverWait(self.driver, 10).until(EC.url_to_be(original_url)) except Exception as e: print(f"点击非导航栏元素失败: {e}") continue # 检查是否非导航栏元素已全部点击 if len(clicked_elements) >= len(non_nav_elements): # 开始点击导航栏元素 for element, element_id in nav_elements: if element_id in clicked_elements: continue try: before_state = self.element_actions.get_page_state() self.element_actions.scroll_to_element(element) self.element_actions.highlight_element(element) self.element_actions.safe_click(element) clicked_elements.add(element_id) print(f"点击导航栏元素: {element_id}") if self.pass_handler(self.driver.current_url): continue self.element_actions.handle_alert() self.element_actions.handle_new_windows(original_window) WebDriverWait(self.driver, 10).until( lambda d: self.element_actions.compare_states(before_state, self.element_actions.get_page_state()) ) if self.driver.current_url != original_url: WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.TAG_NAME, 'body')) ) self.click_all_clickable_elements(clicked_elements, depth=depth + 1) self.driver.back() nav_elements = self.element_actions.get_all_clickable_elements() WebDriverWait(self.driver, 10).until(EC.url_to_be(original_url)) except Exception as e: print(f"点击导航栏元素失败: {e}") continue print("当前页面所有元素已点击完毕")

import os import sys import time import threading import tkinter as tk from tkinter import filedialog, messagebox, ttk from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys import winreg import subprocess # ===== 辅助函数 ===== def find_chromedriver(): """自动查找ChromeDriver""" # 检查当前目录 if os.path.exists("chromedriver.exe"): return os.path.abspath("chromedriver.exe") # 检查PATH环境变量 for path in os.environ["PATH"].split(os.pathsep): driver_path = os.path.join(path, "chromedriver.exe") if os.path.exists(driver_path): return driver_path # 检查Chrome安装路径 try: key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe") chrome_path = winreg.QueryValue(key, None) chrome_dir = os.path.dirname(chrome_path) driver_path = os.path.join(chrome_dir, "chromedriver.exe") if os.path.exists(driver_path): return driver_path except: pass # 检查默认安装位置 paths = [ r"C:\Program Files\Google\Chrome\Application\chromedriver.exe", r"C:\Program Files (x86)\Google\Chrome\Application\chromedriver.exe", os.path.expanduser(r"~\AppData\Local\Google\Chrome\Application\chromedriver.exe") ] for path in paths: if os.path.exists(path): return path return None # ===== 增强版截图类 ===== class EnhancedScreenshot: def __init__(self, driver_path): self.driver_path = driver_path self.options = self._configure_options() self.cookies = {} def _configure_options(self): """配置浏览器选项""" options = Options() options.add_argument("--headless=new") options.add_argument("--disable-gpu") options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") options.add_argument("--window-size=1920,1080") options.add_argument("--force-device-scale-factor=1") options.add_argument("--disable-blink-features=AutomationControlled") options.add_argument("--lang=zh-CN") options.add_experimental_option("excludeSwitches", ["enable-automation"]) options.add_experimental_option('useAutomationExtension', False) # 禁用图片加载加速截图 prefs = {"profile.managed_default_content_settings.images": 2} options.add_experimental_option("prefs", prefs) return options def perform_login(self, driver, username, password, login_url): """执行登录操作""" try: driver.get(login_url) # 等待登录表单出现 WebDriverWait(driver, 15).until( EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='password'], input[name='password']")) ) # 查找用户名和密码输入框 username_fields = driver.find_elements( By.CSS_SELECTOR, "input[type='text'], input[type='email'], input[name='username'], input[name='user'], input[name='email']" ) password_fields = driver.find_elements( By.CSS_SELECTOR, "input[type='password'], input[name='password'], input[name='pass']" ) if username_fields and password_fields: # 输入凭据 username_fields[0].clear() username_fields[0].send_keys(username) password_fields[0].clear() password_fields[0].send_keys(password) # 查找并点击登录按钮 login_buttons = driver.find_elements( By.CSS_SELECTOR, "button[type='submit'], input[type='submit'], .login-btn, .submit-btn" ) if login_buttons: login_buttons[0].click() else: # 如果没有按钮,尝试回车登录 password_fields[0].send_keys(Keys.RETURN) # 等待登录完成 WebDriverWait(driver, 10).until( lambda d: d.current_url != login_url or "登录成功" in d.page_source ) # 保存cookies self.cookies = driver.get_cookies() return True, "登录成功" else: return False, "未找到登录表单" except Exception as e: return False, f"登录失败: {str(e)}" def perform_search(self, driver, search_term): """在页面执行搜索操作""" try: # 尝试查找搜索框 search_selectors = [ "input[type='search']", "input[name='q']", "input[title='搜索']", ".search-input", "#search", "#searchbox", "#searchInput" ] for selector in search_selectors: search_boxes = driver.find_elements(By.CSS_SELECTOR, selector) if search_boxes: search_box = search_boxes[0] search_box.clear() search_box.send_keys(search_term) search_box.send_keys(Keys.RETURN) # 等待搜索结果加载 WebDriverWait(driver, 15).until( EC.presence_of_element_located(( By.CSS_SELECTOR, ".search-results, .result, .s-result-item, .srp, .g" )) ) time.sleep(1.5) # 额外等待 return True, "搜索成功" return False, "未找到搜索框" except Exception as e: return False, f"搜索失败: {str(e)}" def capture(self, url, username=None, password=None, login_url=None, search_term=None): """执行截图操作(支持登录和搜索)""" try: service = Service( executable_path=self.driver_path, service_args=['--log-level=OFF'] ) driver = webdriver.Chrome(service=service, options=self.options) # 绕过自动化检测 driver.execute_cdp_cmd( "Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined }); window.chrome = { runtime: {} }; """ } ) # 步骤1:登录操作(如果需要) if username and password and login_url: login_success, login_msg = self.perform_login(driver, username, password, login_url) if not login_success: return None, f"登录失败: {login_msg}" # 步骤2:导航到目标URL driver.get(url) # 步骤3:执行搜索(如果需要) if search_term: search_success, search_msg = self.perform_search(driver, search_term) if not search_success: return None, f"搜索失败: {search_msg}" # 等待页面加载 WebDriverWait(driver, 20).until( EC.presence_of_element_located((By.TAG_NAME, "body")) ) WebDriverWait(driver, 10).until( lambda d: d.execute_script("return document.readyState") == "complete" ) # 滚动加载动态内容 driver.execute_script(""" // 增强版滚动加载 const scrollHeight = document.body.scrollHeight; const viewportHeight = window.innerHeight; let currentPosition = 0; const scrollStep = viewportHeight * 0.7; function smoothScroll() { if (currentPosition < scrollHeight) { window.scrollTo(0, currentPosition); currentPosition += scrollStep; setTimeout(smoothScroll, 300); } else { window.scrollTo(0, 0); } } smoothScroll(); """) time.sleep(2.5) # 等待滚动完成 # 检查关键元素渲染 driver.execute_script(""" // 强制渲染常见元素 const elementsToRender = [ 'input[type="search"]', '.search-box', '.main-content', '#content' ]; elementsToRender.forEach(selector => { const elements = document.querySelectorAll(selector); elements.forEach(el => { el.style.display = 'block'; if (el.offsetHeight === 0) { el.scrollIntoView({behavior: 'auto', block: 'center'}); } }); }); """) time.sleep(0.5) return driver.get_screenshot_as_png(), None except Exception as e: return None, str(e) finally: try: driver.quit() except: pass # ===== 增强版GUI界面 ===== class EnhancedScreenshotApp: def __init__(self, root): self.root = root root.title("网页截图工具 v2.0") root.geometry("700x600") root.configure(bg="#f0f0f0") # 设置图标(如果存在) try: root.iconbitmap("screenshot_icon.ico") except: pass # 创建选项卡 self.notebook = ttk.Notebook(root) self.notebook.pack(fill='both', expand=True, padx=10, pady=10) # 基本设置选项卡 self.basic_frame = ttk.Frame(self.notebook, padding=10) self.notebook.add(self.basic_frame, text="基本设置") self.create_basic_widgets(self.basic_frame) #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ 精简版网页截图工具 v2.0 功能:登录模块 + 搜索模块 + 智能渲染 """ import os import time import threading import tkinter as tk from tkinter import filedialog, messagebox, ttk from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options 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.keys import Keys class ScreenshotTool: def __init__(self, root): self.root = root root.title("网页截图工具") root.geometry("650x550") # 创建主框架 main_frame = ttk.Frame(root, padding=15) main_frame.pack(fill='both', expand=True) # URL输入 url_frame = ttk.Frame(main_frame) url_frame.pack(fill='x', pady=10) ttk.Label(url_frame, text="目标网址:").pack(side='left') self.url_entry = ttk.Entry(url_frame, width=50) self.url_entry.pack(side='left', padx=5) self.url_entry.insert(0, "https://www.baidu.com") # 登录模块 login_frame = ttk.LabelFrame(main_frame, text="登录设置") login_frame.pack(fill='x', pady=10) # 登录URL ttk.Label(login_frame, text="登录页面:").grid(row=0, column=0, sticky='w', pady=5) self.login_url_entry = ttk.Entry(login_frame, width=45) self.login_url_entry.grid(row=0, column=1, padx=5, pady=5) # 用户名 ttk.Label(login_frame, text="用户名:").grid(row=1, column=0, sticky='w', pady=5) self.user_entry = ttk.Entry(login_frame, width=20) self.user_entry.grid(row=1, column=1, padx=5, pady=5, sticky='w') # 密码 ttk.Label(login_frame, text="密码:").grid(row=2, column=0, sticky='w', pady=5) self.pwd_entry = ttk.Entry(login_frame, width=20, show="*") self.pwd_entry.grid(row=2, column=1, padx=5, pady=5, sticky='w') # 搜索模块 search_frame = ttk.LabelFrame(main_frame, text="搜索设置") search_frame.pack(fill='x', pady=10) ttk.Label(search_frame, text="搜索关键词:").grid(row=0, column=0, sticky='w', pady=5) self.search_entry = ttk.Entry(search_frame, width=45) self.search_entry.grid(row=0, column=1, padx=5, pady=5) # 驱动设置 driver_frame = ttk.Frame(main_frame) driver_frame.pack(fill='x', pady=10) ttk.Label(driver_frame, text="驱动路径:").pack(side='left') self.driver_entry = ttk.Entry(driver_frame, width=40) self.driver_entry.pack(side='left', padx=5) ttk.Button(driver_frame, text="浏览", command=self.browse_driver).pack(side='left') # 截图按钮 self.capture_btn = ttk.Button(main_frame, text="开始截图", command=self.start_capture, width=15) self.capture_btn.pack(pady=15) # 状态栏 self.status = ttk.Label(root, text="就绪", anchor='w', relief='sunken') self.status.pack(fill='x', side='bottom', ipady=5) # 自动检测驱动 self.auto_detect_driver() def browse_driver(self): """浏览选择驱动""" file = filedialog.askopenfilename(title="选择Chrome驱动", filetypes=[("可执行文件", "*.exe")]) if file: self.driver_entry.delete(0, tk.END) self.driver_entry.insert(0, file) def auto_detect_driver(self): """自动检测驱动路径(简化实现)""" common_paths = [ "chromedriver.exe", "C:/Program Files/Google/Chrome/Application/chromedriver.exe", "C:/Program Files (x86)/Google/Chrome/Application/chromedriver.exe" ] for path in common_paths: if os.path.exists(path): self.driver_entry.delete(0, tk.END) self.driver_entry.insert(0, os.path.abspath(path)) return self.status.config(text="警告: 未检测到驱动,请手动选择") def start_capture(self): """启动截图线程""" url = self.url_entry.get().strip() driver_path = self.driver_entry.get() login_url = self.login_url_entry.get().strip() username = self.user_entry.get().strip() password = self.pwd_entry.get().strip() search_term = self.search_entry.get().strip() # 验证输入 if not url.startswith("http"): messagebox.showerror("错误", "请输入有效的URL (以http/https开头)") return if not os.path.exists(driver_path): messagebox.showerror("错误", "驱动路径无效或文件不存在") return # 准备线程 self.capture_btn.config(state=tk.DISABLED, text="截图中...") self.status.config(text=f"开始截图: {url}") threading.Thread( target=self.capture_thread, args=(url, driver_path, login_url, username, password, search_term), daemon=True ).start() def capture_thread(self, url, driver_path, login_url, username, password, search_term): """截图线程核心逻辑""" try: # 配置浏览器选项 options = Options() options.add_argument("--headless=new") options.add_argument("--window-size=1920,1080") options.add_argument("--disable-gpu") options.add_argument("--no-sandbox") options.add_argument("--force-device-scale-factor=1") options.add_experimental_option("excludeSwitches", ["enable-automation"]) # 创建浏览器实例 service = Service(executable_path=driver_path) driver = webdriver.Chrome(service=service, options=options) # 绕过自动化检测 driver.execute_cdp_cmd( "Page.addScriptToEvaluateOnNewDocument", { "source": """Object.defineProperty(navigator, 'webdriver', {get: () => undefined});""" } ) # 登录流程 if login_url and username and password: try: driver.get(login_url) # 等待登录表单 WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CSS_SELECTOR, "input[type='password']")) ) # 查找输入框 user_inputs = driver.find_elements(By.CSS_SELECTOR, "input[type='text'], input[type='email']") pwd_inputs = driver.find_elements(By.CSS_SELECTOR, "input[type='password']") if user_inputs and pwd_inputs: user_inputs[0].send_keys(username) pwd_inputs[0].send_keys(password) pwd_inputs[0].send_keys(Keys.RETURN) time.sleep(2) except Exception as e: self.update_status(f"登录失败: {str(e)}", "red") # 导航到目标页面 driver.get(url) time.sleep(2) # 搜索流程 if search_term: try: search_boxes = driver.find_elements(By.CSS_SELECTOR, "input[type='search'], input[name='q']") if search_boxes: search_boxes[0].send_keys(search_term) search_boxes[0].send_keys(Keys.RETURN) time.sleep(2) except: pass # 智能滚动 driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") time.sleep(1) driver.execute_script("window.scrollTo(0, 0);") time.sleep(0.5) # 保存截图 desktop = os.path.expanduser("~/Desktop") filename = f"screenshot_{time.strftime('%Y%m%d_%H%M%S')}.png" save_path = os.path.join(desktop, filename) driver.save_screenshot(save_path) self.update_status(f"截图成功: {save_path}", "green") os.startfile(save_path) except Exception as e: self.update_status(f"截图失败: {str(e)}", "red") finally: try: driver.quit() except: pass self.root.after(0, lambda: self.capture_btn.config(state=tk.NORMAL, text="开始截图")) def update_status(self, message, color="black"): """更新状态栏""" self.root.after(0, lambda: self.status.config(text=message, foreground=color)) # 启动应用 if __name__ == "__main__": try: from selenium import webdriver except ImportError: print("错误: 请先安装selenium - pip install selenium") sys.exit(1) root = tk.Tk() app = ScreenshotTool(root) root.mainloop() 这个代码是好的,可以截下百度首页的图片,但是设计的关键词输入搜索框里的功能没有实

import time import os import pandas as pd from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.edge.service import Service 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.common.exceptions import InvalidSessionIdException, TimeoutException # 设置Edge驱动路径 edge_driver_path = r'F:\Python\msedgedriver.exe' # 请替换为实际路径 service = Service(edge_driver_path) # 初始化浏览器 options = webdriver.EdgeOptions() driver = webdriver.Edge(service=service, options=options) driver.maximize_window() # 定义一个函数检查会话是否有效 def is_session_valid(driver): try: driver.title return True except InvalidSessionIdException: return False # ---------------------- 搜索与登录流程 ---------------------- # 打开京东首页并搜索"相机" driver.get("https://www.jd.com/") search_box = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "key")) ) search_box.send_keys("相机") search_box.send_keys(Keys.ENTER) # 触发登录(未登录时显示登录提示) try: login_btn = WebDriverWait(driver, 5).until( EC.element_to_be_clickable((By.XPATH, '//a[contains(text(), "你好,请登录")]')) ) login_btn.click() print("正在跳转至登录页...") except Exception as e: print(f"未触发登录,可能已登录: {e}") # ---------------------- 手动登录流程 ---------------------- # 输入账号密码(建议通过配置文件或环境变量管理) username = "15705918760" # 请替换为实际用户名 password = "123456mi" # 请替换为实际密码 try: # 输入用户名 username_input = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "loginname")) ) username_input.clear() username_input.send_keys(username) # 输入密码 password_input = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.ID, "nloginpwd")) ) password_input.clear() password_input.send_keys(password) # 点击登录按钮 login_submit = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.ID, "loginsubmit")) ) login_submit.click() print("请在20秒内手动完成滑动验证码...") time.sleep(20) # 延长手动验证时间 # 验证登录成功 user_info = WebDriverWait(driver, 30).until( EC.presence_of_element_located((By.CLASS_NAME, "nickname")) ) print(f"登录成功,用户:{user_info.text}") except Exception as e: print(f"登录失败:{e}") if is_session_valid(driver): driver.quit() exit() # ---------------------- 按销量排序并爬取 ---------------------- # 优化排序按钮定位方式 try: # 先尝试通过文本定位销量排序按钮 sale_sort = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.XPATH, '//a[contains(text(), "销量")]')) ) # 滚动到排序按钮可见区域 driver.execute_script("arguments[0].scrollIntoView();", sale_sort) sale_sort.click() print("已切换到销量排序") except Exception as e: print(f"尝试通过文本定位销量排序失败:{e}") print("正在尝试通过data-sort属性定位...") try: # 尝试通过data-sort属性定位 sale_sort = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.XPATH, '//a[@data-sort="3"]')) ) driver.execute_script("arguments[0].scrollIntoView();", sale_sort) sale_sort.click() print("已切换到销量排序") except Exception as e2: print(f"排序失败:{e2}") print("直接访问销量排序页面...") # 如果排序按钮定位失败,直接访问销量排序URL driver.get("https://search.jd.com/Search?keyword=相机&enc=utf-8&psort=3") # ---------------------- 商品信息爬取 ---------------------- products = [] page = 1 max_products = 100 max_retries = 3 # 最大重试次数 while len(products) < max_products and is_session_valid(driver): try: print(f"正在爬取第 {page} 页...") retries = 0 while retries < max_retries: try: # 等待商品列表加载(使用XPath定位商品容器) items = WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.XPATH, '//li[contains(@class, "gl-item")]')) ) break except TimeoutException: retries += 1 print(f"第{page}页加载超时,重试第{retries}次...") if retries == max_retries: print(f"第{page}页加载失败,跳过此页") break for item in items: if len(products) >= max_products: break try: # 提取价格(使用XPath确保稳定性) price = WebDriverWait(item, 5).until( EC.presence_of_element_located((By.XPATH, './/i[@class="J_price"]')) ).text.strip() # 提取标题 title = item.find_element(By.XPATH, './/div[@class="p-name"]/a/em').text.strip() # 提取图片URL img_url = item.find_element(By.XPATH, './/img[@data-lazy-img]').get_attribute("data-lazy-img") if img_url.startswith("//"): img_url = "https:" + img_url # 提取店铺名称 shop_name = item.find_element(By.XPATH, './/span[@class="J_im_icon"]/a').text.strip() products.append({ "排名": len(products) + 1, "价格": price, "标题": title, "图片URL": img_url, "店铺名称": shop_name }) print(f"已爬取 {len(products)}/{max_products}: {title}") except InvalidSessionIdException: print("会话失效,终止爬取") break except Exception as e: print(f"解析商品出错:{e}") continue # 翻页(使用XPath定位下一页按钮) if len(products) < max_products and is_session_valid(driver): try: next_page = WebDriverWait(driver, 10).until( EC.element_to_be_clickable((By.XPATH, '//a[text()="下一页"]')) ) next_page.click() page += 1 time.sleep(3) # 翻页后等待加载 except TimeoutException: print("下一页按钮加载超时,终止爬取") break except InvalidSessionIdException: print("会话失效,终止爬取") break except Exception as e: print(f"翻页出错:{e},尝试直接跳转至第{page+1}页") # 备用翻页方式:直接修改URL页码 current_url = driver.current_url if 'page=' in current_url: new_url = current_url.split('page=')[0] + f'page={page+1}' else: new_url = current_url + f'&page={page+1}' driver.get(new_url) page += 1 time.sleep(5) except InvalidSessionIdException: print("会话失效,终止爬取") break # ---------------------- 关闭浏览器 ---------------------- if is_session_valid(driver): driver.quit() # ---------------------- 保存数据到Excel ---------------------- try: save_dir = r"F:\小组作业" os.makedirs(save_dir, exist_ok=True) excel_path = os.path.join(save_dir, "京东相机商品信息.xlsx") df = pd.DataFrame(products) df.to_excel(excel_path, index=False) print(f"数据已成功保存至 {excel_path}") except Exception as e: print(f"保存失败:{e}")

PS C:\Users\Administrator\Desktop\web8> & D:/Python/python.exe c:/Users/Administrator/Desktop/web8/CMG_024_test.py CMG_024_test.py::Test_CMG024::test_add_qvlan ------------------------------------------------------------------------------------ live log setup ------------------------------------------------------------------------------------- 17:20:16 - MyBaseTest - INFO - url:::http://192.168.11.110:5066/api/TestReport/create-report 17:20:16 - MyBaseTest - INFO - Report Create successfully. Report ID: 317 17:20:18 - MyBaseTest - INFO - Base Proxy address:localhost:8081 DevTools listening on ws://127.0.0.1:58322/devtools/browser/265bb708-e8e6-4d4b-9376-b87f130d5136 [26244:19408:0809/172019.494:ERROR:sandbox_win.cc(840)] Sandbox cannot access executable. Check filesystem permissions are valid. See https://bit.ly/31yqMJR.: 鎷掔粷璁块棶銆?(0x5) [26244:22000:0809/172019.591:ERROR:network_service_instance_impl.cc(600)] Network service crashed, restarting service. 17:20:34 - MyBaseTest - ERROR - Sign in Error ERROR [ 33%] CMG_024_test.py::Test_CMG024::test_add_qvlan_port[1234] ERROR [ 66%] CMG_024_test.py::Test_CMG024::test_qvlan_boundary ERROR [100%] ======================================================================================== ERRORS ========================================================================================= _____________________________________________________________________ ERROR at setup of Test_CMG024.test_add_qvlan ______________________________________________________________________ self = <MyBaseTest.BaseTest object at 0x000002680CCA0AD0> def sign_in(self): """执行登录操作(中文版)""" try: self.driver.get(self.dev_ip) time.sleep(3.5) > WebDriverWait(self.driver, 5).until( EC.visibility_of_element_located((By.ID, "password")) ) MyBaseTest.py:303: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ D:\Python\Lib\site-packages\selenium\webdriver\support\wait.py:129: in until value = method(self._driver) ^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\support\expected_conditions.py:217: in _predicate return _element_if_visible(driver.find_element(*locator)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:922: in find_element return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:454: in execute self.error_handler.check_response(response) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x000002680CCA12B0> response = {'status': 404, 'value': '{"value":{"error":"no such window","message":"no such window: target window already closed\\...07FF74CAEA3EF]\\n\\tBaseThreadInitThunk [0x00007FFAFC6FE8D7+23]\\n\\tRtlUserThreadStart [0x00007FFAFD7BC34C+44]\\n"}}'} def check_response(self, response: dict[str, Any]) -> None: """Checks that a JSON response from the WebDriver does not have an error. :Args: - response - The JSON response from the WebDriver server as a dictionary object. :Raises: If the response contains an error message. """ status = response.get("status", None) if not status or status == ErrorCode.SUCCESS: return value = None message = response.get("message", "") screen: str = response.get("screen", "") stacktrace = None if isinstance(status, int): value_json = response.get("value", None) if value_json and isinstance(value_json, str): try: value = json.loads(value_json) if isinstance(value, dict): if len(value) == 1: value = value["value"] status = value.get("error", None) if not status: status = value.get("status", ErrorCode.UNKNOWN_ERROR) message = value.get("value") or value.get("message") if not isinstance(message, str): value = message message = message.get("message") else: message = value.get("message", None) except ValueError: pass exception_class: type[WebDriverException] e = ErrorCode() error_codes = [item for item in dir(e) if not item.startswith("__")] for error_code in error_codes: error_info = getattr(ErrorCode, error_code) if isinstance(error_info, list) and status in error_info: exception_class = getattr(ExceptionMapping, error_code, WebDriverException) break else: exception_class = WebDriverException if not value: value = response["value"] if isinstance(value, str): raise exception_class(value) if message == "" and "message" in value: message = value["message"] screen = None # type: ignore[assignment] if "screen" in value: screen = value["screen"] stacktrace = None st_value = value.get("stackTrace") or value.get("stacktrace") if st_value: if isinstance(st_value, str): stacktrace = st_value.split("\n") else: stacktrace = [] try: for frame in st_value: line = frame.get("lineNumber", "") file = frame.get("fileName", "<anonymous>") if line: file = f"{file}:{line}" meth = frame.get("methodName", "<anonymous>") if "className" in frame: meth = f"{frame['className']}.{meth}" msg = " at %s (%s)" msg = msg % (meth, file) stacktrace.append(msg) except TypeError: pass if exception_class == UnexpectedAlertPresentException: alert_text = None if "data" in value: alert_text = value["data"].get("text") elif "alert" in value: alert_text = value["alert"].get("text") raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here > raise exception_class(message, screen, stacktrace) E selenium.common.exceptions.NoSuchWindowException: Message: no such window: target window already closed E from unknown error: web view not found E (Session info: chrome=127.0.6533.99) E Stacktrace: E GetHandleVerifier [0x00007FF74CB39632+30946] E (No symbol) [0x00007FF74CAEE3C9] E (No symbol) [0x00007FF74C9E6FDA] E (No symbol) [0x00007FF74C9BCB85] E (No symbol) [0x00007FF74CA637A7] E (No symbol) [0x00007FF74CA7A771] E (No symbol) [0x00007FF74CA5C813] E (No symbol) [0x00007FF74CA2A6E5] E (No symbol) [0x00007FF74CA2B021] E GetHandleVerifier [0x00007FF74CC6F83D+1301229] E GetHandleVerifier [0x00007FF74CC7BDB7+1351783] E GetHandleVerifier [0x00007FF74CC72A03+1313971] E GetHandleVerifier [0x00007FF74CB6DD06+245686] E (No symbol) [0x00007FF74CAF758F] E (No symbol) [0x00007FF74CAF3804] E (No symbol) [0x00007FF74CAF3992] E (No symbol) [0x00007FF74CAEA3EF] E BaseThreadInitThunk [0x00007FFAFC6FE8D7+23] E RtlUserThreadStart [0x00007FFAFD7BC34C+44] D:\Python\Lib\site-packages\selenium\webdriver\remote\errorhandler.py:232: NoSuchWindowException During handling of the above exception, another exception occurred: request = <SubRequest 'get_driver' for <Function test_add_qvlan>>, setup_browsermob_proxy = <MyBaseTest.BaseTest object at 0x000002680CCA0AD0> @pytest.fixture(scope="class") def get_driver(request,setup_browsermob_proxy): # 自动登陆实现 setup_browsermob_proxy.load_config() > setup_browsermob_proxy.sign_in() conftest.py:112: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ MyBaseTest.py:336: in sign_in self.take_screenshot("Sign_Error") MyBaseTest.py:250: in take_screenshot self.driver.save_screenshot(screenshot_path) D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:1021: in save_screenshot return self.get_screenshot_as_file(filename) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:996: in get_screenshot_as_file png = self.get_screenshot_as_png() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:1030: in get_screenshot_as_png return b64decode(self.get_screenshot_as_base64().encode("ascii")) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:1040: in get_screenshot_as_base64 return self.execute(Command.SCREENSHOT)["value"] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:454: in execute self.error_handler.check_response(response) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x000002680CCA12B0> response = {'status': 404, 'value': '{"value":{"error":"no such window","message":"no such window: target window already closed\\...07FF74CAEA3EF]\\n\\tBaseThreadInitThunk [0x00007FFAFC6FE8D7+23]\\n\\tRtlUserThreadStart [0x00007FFAFD7BC34C+44]\\n"}}'} def check_response(self, response: dict[str, Any]) -> None: """Checks that a JSON response from the WebDriver does not have an error. :Args: - response - The JSON response from the WebDriver server as a dictionary object. :Raises: If the response contains an error message. """ status = response.get("status", None) if not status or status == ErrorCode.SUCCESS: return value = None message = response.get("message", "") screen: str = response.get("screen", "") stacktrace = None if isinstance(status, int): value_json = response.get("value", None) if value_json and isinstance(value_json, str): try: value = json.loads(value_json) if isinstance(value, dict): if len(value) == 1: value = value["value"] status = value.get("error", None) if not status: status = value.get("status", ErrorCode.UNKNOWN_ERROR) message = value.get("value") or value.get("message") if not isinstance(message, str): value = message message = message.get("message") else: message = value.get("message", None) except ValueError: pass exception_class: type[WebDriverException] e = ErrorCode() error_codes = [item for item in dir(e) if not item.startswith("__")] for error_code in error_codes: error_info = getattr(ErrorCode, error_code) if isinstance(error_info, list) and status in error_info: exception_class = getattr(ExceptionMapping, error_code, WebDriverException) break else: exception_class = WebDriverException if not value: value = response["value"] if isinstance(value, str): raise exception_class(value) if message == "" and "message" in value: message = value["message"] screen = None # type: ignore[assignment] if "screen" in value: screen = value["screen"] stacktrace = None st_value = value.get("stackTrace") or value.get("stacktrace") if st_value: if isinstance(st_value, str): stacktrace = st_value.split("\n") else: stacktrace = [] try: for frame in st_value: line = frame.get("lineNumber", "") file = frame.get("fileName", "<anonymous>") if line: file = f"{file}:{line}" meth = frame.get("methodName", "<anonymous>") if "className" in frame: meth = f"{frame['className']}.{meth}" msg = " at %s (%s)" msg = msg % (meth, file) stacktrace.append(msg) except TypeError: pass if exception_class == UnexpectedAlertPresentException: alert_text = None if "data" in value: alert_text = value["data"].get("text") elif "alert" in value: alert_text = value["alert"].get("text") raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here > raise exception_class(message, screen, stacktrace) E selenium.common.exceptions.NoSuchWindowException: Message: no such window: target window already closed E from unknown error: web view not found E (Session info: chrome=127.0.6533.99) E Stacktrace: E GetHandleVerifier [0x00007FF74CB39632+30946] E (No symbol) [0x00007FF74CAEE3C9] E (No symbol) [0x00007FF74C9E6FDA] E (No symbol) [0x00007FF74C9BCB85] E (No symbol) [0x00007FF74CA637A7] E (No symbol) [0x00007FF74CA7A771] E (No symbol) [0x00007FF74CA5C813] E (No symbol) [0x00007FF74CA2A6E5] E (No symbol) [0x00007FF74CA2B021] E GetHandleVerifier [0x00007FF74CC6F83D+1301229] E GetHandleVerifier [0x00007FF74CC7BDB7+1351783] E GetHandleVerifier [0x00007FF74CC72A03+1313971] E GetHandleVerifier [0x00007FF74CB6DD06+245686] E (No symbol) [0x00007FF74CAF758F] E (No symbol) [0x00007FF74CAF3804] E (No symbol) [0x00007FF74CAF3992] E (No symbol) [0x00007FF74CAEA3EF] E BaseThreadInitThunk [0x00007FFAFC6FE8D7+23] E RtlUserThreadStart [0x00007FFAFD7BC34C+44] D:\Python\Lib\site-packages\selenium\webdriver\remote\errorhandler.py:232: NoSuchWindowException ---------------------------------------------------------------------------------- Captured log setup ----------------------------------------------------------------------------------- INFO MyBaseTest:MyBaseTest.py:758 url:::http://192.168.11.110:5066/api/TestReport/create-report INFO MyBaseTest:MyBaseTest.py:773 Report Create successfully. Report ID: 317 INFO MyBaseTest:MyBaseTest.py:62 Base Proxy address:localhost:8081 ERROR MyBaseTest:MyBaseTest.py:335 Sign in Error ________________________________________________________________ ERROR at setup of Test_CMG024.test_add_qvlan_port[1234] ________________________________________________________________ self = <MyBaseTest.BaseTest object at 0x000002680CCA0AD0> def sign_in(self): """执行登录操作(中文版)""" try: self.driver.get(self.dev_ip) time.sleep(3.5) > WebDriverWait(self.driver, 5).until( EC.visibility_of_element_located((By.ID, "password")) ) MyBaseTest.py:303: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ D:\Python\Lib\site-packages\selenium\webdriver\support\wait.py:129: in until value = method(self._driver) ^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\support\expected_conditions.py:217: in _predicate return _element_if_visible(driver.find_element(*locator)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:922: in find_element return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:454: in execute self.error_handler.check_response(response) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x000002680CCA12B0> response = {'status': 404, 'value': '{"value":{"error":"no such window","message":"no such window: target window already closed\\...07FF74CAEA3EF]\\n\\tBaseThreadInitThunk [0x00007FFAFC6FE8D7+23]\\n\\tRtlUserThreadStart [0x00007FFAFD7BC34C+44]\\n"}}'} def check_response(self, response: dict[str, Any]) -> None: """Checks that a JSON response from the WebDriver does not have an error. :Args: - response - The JSON response from the WebDriver server as a dictionary object. :Raises: If the response contains an error message. """ status = response.get("status", None) if not status or status == ErrorCode.SUCCESS: return value = None message = response.get("message", "") screen: str = response.get("screen", "") stacktrace = None if isinstance(status, int): value_json = response.get("value", None) if value_json and isinstance(value_json, str): try: value = json.loads(value_json) if isinstance(value, dict): if len(value) == 1: value = value["value"] status = value.get("error", None) if not status: status = value.get("status", ErrorCode.UNKNOWN_ERROR) message = value.get("value") or value.get("message") if not isinstance(message, str): value = message message = message.get("message") else: message = value.get("message", None) except ValueError: pass exception_class: type[WebDriverException] e = ErrorCode() error_codes = [item for item in dir(e) if not item.startswith("__")] for error_code in error_codes: error_info = getattr(ErrorCode, error_code) if isinstance(error_info, list) and status in error_info: exception_class = getattr(ExceptionMapping, error_code, WebDriverException) break else: exception_class = WebDriverException if not value: value = response["value"] if isinstance(value, str): raise exception_class(value) if message == "" and "message" in value: message = value["message"] screen = None # type: ignore[assignment] if "screen" in value: screen = value["screen"] stacktrace = None st_value = value.get("stackTrace") or value.get("stacktrace") if st_value: if isinstance(st_value, str): stacktrace = st_value.split("\n") else: stacktrace = [] try: for frame in st_value: line = frame.get("lineNumber", "") file = frame.get("fileName", "<anonymous>") if line: file = f"{file}:{line}" meth = frame.get("methodName", "<anonymous>") if "className" in frame: meth = f"{frame['className']}.{meth}" msg = " at %s (%s)" msg = msg % (meth, file) stacktrace.append(msg) except TypeError: pass if exception_class == UnexpectedAlertPresentException: alert_text = None if "data" in value: alert_text = value["data"].get("text") elif "alert" in value: alert_text = value["alert"].get("text") raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here > raise exception_class(message, screen, stacktrace) E selenium.common.exceptions.NoSuchWindowException: Message: no such window: target window already closed E from unknown error: web view not found E (Session info: chrome=127.0.6533.99) E Stacktrace: E GetHandleVerifier [0x00007FF74CB39632+30946] E (No symbol) [0x00007FF74CAEE3C9] E (No symbol) [0x00007FF74C9E6FDA] E (No symbol) [0x00007FF74C9BCB85] E (No symbol) [0x00007FF74CA637A7] E (No symbol) [0x00007FF74CA7A771] E (No symbol) [0x00007FF74CA5C813] E (No symbol) [0x00007FF74CA2A6E5] E (No symbol) [0x00007FF74CA2B021] E GetHandleVerifier [0x00007FF74CC6F83D+1301229] E GetHandleVerifier [0x00007FF74CC7BDB7+1351783] E GetHandleVerifier [0x00007FF74CC72A03+1313971] E GetHandleVerifier [0x00007FF74CB6DD06+245686] E (No symbol) [0x00007FF74CAF758F] E (No symbol) [0x00007FF74CAF3804] E (No symbol) [0x00007FF74CAF3992] E (No symbol) [0x00007FF74CAEA3EF] E BaseThreadInitThunk [0x00007FFAFC6FE8D7+23] E RtlUserThreadStart [0x00007FFAFD7BC34C+44] D:\Python\Lib\site-packages\selenium\webdriver\remote\errorhandler.py:232: NoSuchWindowException During handling of the above exception, another exception occurred: request = <SubRequest 'get_driver' for <Function test_add_qvlan>>, setup_browsermob_proxy = <MyBaseTest.BaseTest object at 0x000002680CCA0AD0> @pytest.fixture(scope="class") def get_driver(request,setup_browsermob_proxy): # 自动登陆实现 setup_browsermob_proxy.load_config() > setup_browsermob_proxy.sign_in() conftest.py:112: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ MyBaseTest.py:336: in sign_in self.take_screenshot("Sign_Error") MyBaseTest.py:250: in take_screenshot self.driver.save_screenshot(screenshot_path) D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:1021: in save_screenshot return self.get_screenshot_as_file(filename) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:996: in get_screenshot_as_file png = self.get_screenshot_as_png() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:1030: in get_screenshot_as_png return b64decode(self.get_screenshot_as_base64().encode("ascii")) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:1040: in get_screenshot_as_base64 return self.execute(Command.SCREENSHOT)["value"] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:454: in execute self.error_handler.check_response(response) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x000002680CCA12B0> response = {'status': 404, 'value': '{"value":{"error":"no such window","message":"no such window: target window already closed\\...07FF74CAEA3EF]\\n\\tBaseThreadInitThunk [0x00007FFAFC6FE8D7+23]\\n\\tRtlUserThreadStart [0x00007FFAFD7BC34C+44]\\n"}}'} def check_response(self, response: dict[str, Any]) -> None: """Checks that a JSON response from the WebDriver does not have an error. :Args: - response - The JSON response from the WebDriver server as a dictionary object. :Raises: If the response contains an error message. """ status = response.get("status", None) if not status or status == ErrorCode.SUCCESS: return value = None message = response.get("message", "") screen: str = response.get("screen", "") stacktrace = None if isinstance(status, int): value_json = response.get("value", None) if value_json and isinstance(value_json, str): try: value = json.loads(value_json) if isinstance(value, dict): if len(value) == 1: value = value["value"] status = value.get("error", None) if not status: status = value.get("status", ErrorCode.UNKNOWN_ERROR) message = value.get("value") or value.get("message") if not isinstance(message, str): value = message message = message.get("message") else: message = value.get("message", None) except ValueError: pass exception_class: type[WebDriverException] e = ErrorCode() error_codes = [item for item in dir(e) if not item.startswith("__")] for error_code in error_codes: error_info = getattr(ErrorCode, error_code) if isinstance(error_info, list) and status in error_info: exception_class = getattr(ExceptionMapping, error_code, WebDriverException) break else: exception_class = WebDriverException if not value: value = response["value"] if isinstance(value, str): raise exception_class(value) if message == "" and "message" in value: message = value["message"] screen = None # type: ignore[assignment] if "screen" in value: screen = value["screen"] stacktrace = None st_value = value.get("stackTrace") or value.get("stacktrace") if st_value: if isinstance(st_value, str): stacktrace = st_value.split("\n") else: stacktrace = [] try: for frame in st_value: line = frame.get("lineNumber", "") file = frame.get("fileName", "<anonymous>") if line: file = f"{file}:{line}" meth = frame.get("methodName", "<anonymous>") if "className" in frame: meth = f"{frame['className']}.{meth}" msg = " at %s (%s)" msg = msg % (meth, file) stacktrace.append(msg) except TypeError: pass if exception_class == UnexpectedAlertPresentException: alert_text = None if "data" in value: alert_text = value["data"].get("text") elif "alert" in value: alert_text = value["alert"].get("text") raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here > raise exception_class(message, screen, stacktrace) E selenium.common.exceptions.NoSuchWindowException: Message: no such window: target window already closed E from unknown error: web view not found E (Session info: chrome=127.0.6533.99) E Stacktrace: E GetHandleVerifier [0x00007FF74CB39632+30946] E (No symbol) [0x00007FF74CAEE3C9] E (No symbol) [0x00007FF74C9E6FDA] E (No symbol) [0x00007FF74C9BCB85] E (No symbol) [0x00007FF74CA637A7] E (No symbol) [0x00007FF74CA7A771] E (No symbol) [0x00007FF74CA5C813] E (No symbol) [0x00007FF74CA2A6E5] E (No symbol) [0x00007FF74CA2B021] E GetHandleVerifier [0x00007FF74CC6F83D+1301229] E GetHandleVerifier [0x00007FF74CC7BDB7+1351783] E GetHandleVerifier [0x00007FF74CC72A03+1313971] E GetHandleVerifier [0x00007FF74CB6DD06+245686] E (No symbol) [0x00007FF74CAF758F] E (No symbol) [0x00007FF74CAF3804] E (No symbol) [0x00007FF74CAF3992] E (No symbol) [0x00007FF74CAEA3EF] E BaseThreadInitThunk [0x00007FFAFC6FE8D7+23] E RtlUserThreadStart [0x00007FFAFD7BC34C+44] D:\Python\Lib\site-packages\selenium\webdriver\remote\errorhandler.py:232: NoSuchWindowException ___________________________________________________________________ ERROR at setup of Test_CMG024.test_qvlan_boundary ___________________________________________________________________ self = <MyBaseTest.BaseTest object at 0x000002680CCA0AD0> def sign_in(self): """执行登录操作(中文版)""" try: self.driver.get(self.dev_ip) time.sleep(3.5) > WebDriverWait(self.driver, 5).until( EC.visibility_of_element_located((By.ID, "password")) ) MyBaseTest.py:303: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ D:\Python\Lib\site-packages\selenium\webdriver\support\wait.py:129: in until value = method(self._driver) ^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\support\expected_conditions.py:217: in _predicate return _element_if_visible(driver.find_element(*locator)) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:922: in find_element return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:454: in execute self.error_handler.check_response(response) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x000002680CCA12B0> response = {'status': 404, 'value': '{"value":{"error":"no such window","message":"no such window: target window already closed\\...07FF74CAEA3EF]\\n\\tBaseThreadInitThunk [0x00007FFAFC6FE8D7+23]\\n\\tRtlUserThreadStart [0x00007FFAFD7BC34C+44]\\n"}}'} def check_response(self, response: dict[str, Any]) -> None: """Checks that a JSON response from the WebDriver does not have an error. :Args: - response - The JSON response from the WebDriver server as a dictionary object. :Raises: If the response contains an error message. """ status = response.get("status", None) if not status or status == ErrorCode.SUCCESS: return value = None message = response.get("message", "") screen: str = response.get("screen", "") stacktrace = None if isinstance(status, int): value_json = response.get("value", None) if value_json and isinstance(value_json, str): try: value = json.loads(value_json) if isinstance(value, dict): if len(value) == 1: value = value["value"] status = value.get("error", None) if not status: status = value.get("status", ErrorCode.UNKNOWN_ERROR) message = value.get("value") or value.get("message") if not isinstance(message, str): value = message message = message.get("message") else: message = value.get("message", None) except ValueError: pass exception_class: type[WebDriverException] e = ErrorCode() error_codes = [item for item in dir(e) if not item.startswith("__")] for error_code in error_codes: error_info = getattr(ErrorCode, error_code) if isinstance(error_info, list) and status in error_info: exception_class = getattr(ExceptionMapping, error_code, WebDriverException) break else: exception_class = WebDriverException if not value: value = response["value"] if isinstance(value, str): raise exception_class(value) if message == "" and "message" in value: message = value["message"] screen = None # type: ignore[assignment] if "screen" in value: screen = value["screen"] stacktrace = None st_value = value.get("stackTrace") or value.get("stacktrace") if st_value: if isinstance(st_value, str): stacktrace = st_value.split("\n") else: stacktrace = [] try: for frame in st_value: line = frame.get("lineNumber", "") file = frame.get("fileName", "<anonymous>") if line: file = f"{file}:{line}" meth = frame.get("methodName", "<anonymous>") if "className" in frame: meth = f"{frame['className']}.{meth}" msg = " at %s (%s)" msg = msg % (meth, file) stacktrace.append(msg) except TypeError: pass if exception_class == UnexpectedAlertPresentException: alert_text = None if "data" in value: alert_text = value["data"].get("text") elif "alert" in value: alert_text = value["alert"].get("text") raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here > raise exception_class(message, screen, stacktrace) E selenium.common.exceptions.NoSuchWindowException: Message: no such window: target window already closed E from unknown error: web view not found E (Session info: chrome=127.0.6533.99) E Stacktrace: E GetHandleVerifier [0x00007FF74CB39632+30946] E (No symbol) [0x00007FF74CAEE3C9] E (No symbol) [0x00007FF74C9E6FDA] E (No symbol) [0x00007FF74C9BCB85] E (No symbol) [0x00007FF74CA637A7] E (No symbol) [0x00007FF74CA7A771] E (No symbol) [0x00007FF74CA5C813] E (No symbol) [0x00007FF74CA2A6E5] E (No symbol) [0x00007FF74CA2B021] E GetHandleVerifier [0x00007FF74CC6F83D+1301229] E GetHandleVerifier [0x00007FF74CC7BDB7+1351783] E GetHandleVerifier [0x00007FF74CC72A03+1313971] E GetHandleVerifier [0x00007FF74CB6DD06+245686] E (No symbol) [0x00007FF74CAF758F] E (No symbol) [0x00007FF74CAF3804] E (No symbol) [0x00007FF74CAF3992] E (No symbol) [0x00007FF74CAEA3EF] E BaseThreadInitThunk [0x00007FFAFC6FE8D7+23] E RtlUserThreadStart [0x00007FFAFD7BC34C+44] D:\Python\Lib\site-packages\selenium\webdriver\remote\errorhandler.py:232: NoSuchWindowException During handling of the above exception, another exception occurred: request = <SubRequest 'get_driver' for <Function test_add_qvlan>>, setup_browsermob_proxy = <MyBaseTest.BaseTest object at 0x000002680CCA0AD0> @pytest.fixture(scope="class") def get_driver(request,setup_browsermob_proxy): # 自动登陆实现 setup_browsermob_proxy.load_config() > setup_browsermob_proxy.sign_in() conftest.py:112: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ MyBaseTest.py:336: in sign_in self.take_screenshot("Sign_Error") MyBaseTest.py:250: in take_screenshot self.driver.save_screenshot(screenshot_path) D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:1021: in save_screenshot return self.get_screenshot_as_file(filename) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:996: in get_screenshot_as_file png = self.get_screenshot_as_png() ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:1030: in get_screenshot_as_png return b64decode(self.get_screenshot_as_base64().encode("ascii")) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:1040: in get_screenshot_as_base64 return self.execute(Command.SCREENSHOT)["value"] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ D:\Python\Lib\site-packages\selenium\webdriver\remote\webdriver.py:454: in execute self.error_handler.check_response(response) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x000002680CCA12B0> response = {'status': 404, 'value': '{"value":{"error":"no such window","message":"no such window: target window already closed\\...07FF74CAEA3EF]\\n\\tBaseThreadInitThunk [0x00007FFAFC6FE8D7+23]\\n\\tRtlUserThreadStart [0x00007FFAFD7BC34C+44]\\n"}}'} def check_response(self, response: dict[str, Any]) -> None: """Checks that a JSON response from the WebDriver does not have an error. :Args: - response - The JSON response from the WebDriver server as a dictionary object. :Raises: If the response contains an error message. """ status = response.get("status", None) if not status or status == ErrorCode.SUCCESS: return value = None message = response.get("message", "") screen: str = response.get("screen", "") stacktrace = None if isinstance(status, int): value_json = response.get("value", None) if value_json and isinstance(value_json, str): try: value = json.loads(value_json) if isinstance(value, dict): if len(value) == 1: value = value["value"] status = value.get("error", None) if not status: status = value.get("status", ErrorCode.UNKNOWN_ERROR) message = value.get("value") or value.get("message") if not isinstance(message, str): value = message message = message.get("message") else: message = value.get("message", None) except ValueError: pass exception_class: type[WebDriverException] e = ErrorCode() error_codes = [item for item in dir(e) if not item.startswith("__")] for error_code in error_codes: error_info = getattr(ErrorCode, error_code) if isinstance(error_info, list) and status in error_info: exception_class = getattr(ExceptionMapping, error_code, WebDriverException) break else: exception_class = WebDriverException if not value: value = response["value"] if isinstance(value, str): raise exception_class(value) if message == "" and "message" in value: message = value["message"] screen = None # type: ignore[assignment] if "screen" in value: screen = value["screen"] stacktrace = None st_value = value.get("stackTrace") or value.get("stacktrace") if st_value: if isinstance(st_value, str): stacktrace = st_value.split("\n") else: stacktrace = [] try: for frame in st_value: line = frame.get("lineNumber", "") file = frame.get("fileName", "<anonymous>") if line: file = f"{file}:{line}" meth = frame.get("methodName", "<anonymous>") if "className" in frame: meth = f"{frame['className']}.{meth}" msg = " at %s (%s)" msg = msg % (meth, file) stacktrace.append(msg) except TypeError: pass if exception_class == UnexpectedAlertPresentException: alert_text = None if "data" in value: alert_text = value["data"].get("text") elif "alert" in value: alert_text = value["alert"].get("text") raise exception_class(message, screen, stacktrace, alert_text) # type: ignore[call-arg] # mypy is not smart enough here > raise exception_class(message, screen, stacktrace) E selenium.common.exceptions.NoSuchWindowException: Message: no such window: target window already closed E from unknown error: web view not found E (Session info: chrome=127.0.6533.99) E Stacktrace: E GetHandleVerifier [0x00007FF74CB39632+30946] E (No symbol) [0x00007FF74CAEE3C9] E (No symbol) [0x00007FF74C9E6FDA] E (No symbol) [0x00007FF74C9BCB85] E (No symbol) [0x00007FF74CA637A7] E (No symbol) [0x00007FF74CA7A771] E (No symbol) [0x00007FF74CA5C813] E (No symbol) [0x00007FF74CA2A6E5] E (No symbol) [0x00007FF74CA2B021] E GetHandleVerifier [0x00007FF74CC6F83D+1301229] E GetHandleVerifier [0x00007FF74CC7BDB7+1351783] E GetHandleVerifier [0x00007FF74CC72A03+1313971] E GetHandleVerifier [0x00007FF74CB6DD06+245686] E (No symbol) [0x00007FF74CAF758F] E (No symbol) [0x00007FF74CAF3804] E (No symbol) [0x00007FF74CAF3992] E (No symbol) [0x00007FF74CAEA3EF] E BaseThreadInitThunk [0x00007FFAFC6FE8D7+23] E RtlUserThreadStart [0x00007FFAFD7BC34C+44] D:\Python\Lib\site-packages\selenium\webdriver\remote\errorhandler.py:232: NoSuchWindowException =================================================================================== warnings summary ==================================================================================== CMG_024_test.py:232 c:\Users\Administrator\Desktop\web8\CMG_024_test.py:232: PytestUnknownMarkWarning: Unknown pytest.mark.repeat - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html @pytest.mark.repeat(6) -- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html -------------------------------------------------------- generated xml file: C:\Users\Administrator\Desktop\web8\testresults.xml -------------------------------------------------------- HTTP error occurred: 404 Client Error: Not Found for url: http://192.168.11.110:5066/api/TestReport/upload-test-summary?reportId=0&endTime=1754731236491 ------------------------------------------------- Generated html report: file:///C:/Users/Administrator/Desktop/web8/report/report.html ------------------------------------------------- ================================================================================ short test summary info ================================================================================ ERROR CMG_024_test.py::Test_CMG024::test_add_qvlan - selenium.common.exceptions.NoSuchWindowException: Message: no such window: target window already closed ERROR CMG_024_test.py::Test_CMG024::test_add_qvlan_port[1234] - selenium.common.exceptions.NoSuchWindowException: Message: no such window: target window already closed ERROR CMG_024_test.py::Test_CMG024::test_qvlan_boundary - selenium.common.exceptions.NoSuchWindowException: Message: no such window: target window already closed ============================================================================= 1 warning, 3 errors in 20.23s ============================================================================= PS C:\Users\Administrator\Desktop\web8>

import platform import shutil import os import re import threading import tkinter as tk import urllib.request import zipfile import json import time try: import winreg # Windows专用 except ImportError: pass import subprocess from tkinter import filedialog, messagebox, ttk from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.chrome.options import Options from selenium.common.exceptions import (WebDriverException, SessionNotCreatedException, NoSuchElementException) class WebScreenshotApp: def __init__(self, root): self.root = root root.title("网页截图工具 v2.0") root.geometry("800x600") root.resizable(True, True) # 创建主框架 main_frame = ttk.Frame(root, padding="20") main_frame.pack(fill=tk.BOTH, expand=True) # 创建输入区域 input_frame = ttk.LabelFrame(main_frame, text="截图参数", padding=10) input_frame.pack(fill=tk.X, pady=(0, 10)) # URL输入 ttk.Label(input_frame, text="目标网址:").grid(row=0, column=0, sticky="w", padx=5, pady=5) self.url_entry = ttk.Entry(input_frame, width=50) self.url_entry.grid(row=0, column=1, columnspan=2, sticky="we", padx=5, pady=5) self.url_entry.insert(0, "https://example.com") # 登录凭证(可选) auth_frame = ttk.Frame(input_frame) auth_frame.grid(row=1, column=0, columnspan=3, sticky="we", pady=5) ttk.Label(auth_frame, text="用户名:").pack(side=tk.LEFT, padx=(0, 5)) self.user_entry = ttk.Entry(auth_frame, width=20) self.user_entry.pack(side=tk.LEFT, padx=(0, 10)) ttk.Label(auth_frame, text="密码:").pack(side=tk.LEFT) self.pass_entry = ttk.Entry(auth_frame, width=20, show="*") self.pass_entry.pack(side=tk.LEFT, padx=(0, 10)) # 关键词搜索(可选) ttk.Label(input_frame, text="搜索关键词:").grid(row=2, column=0, sticky="w", padx=5, pady=5) self.search_entry = ttk.Entry(input_frame, width=50) self.search_entry.grid(row=2, column=1, columnspan=2, sticky="we", padx=5, pady=5) # 驱动设置区域 driver_frame = ttk.LabelFrame(main_frame, text="Chrome驱动设置", padding=10) driver_frame.pack(fill=tk.X, pady=(0, 10)) ttk.Label(driver_frame, text="驱动路径:").grid(row=0, column=0, sticky="w", padx=5, pady=5) self.driver_entry = ttk.Entry(driver_frame, width=50) self.driver_entry.grid(row=0, column=1, sticky="we", padx=5, pady=5) ttk.Button(driver_frame, text="浏览...", width=10, command=self.browse_driver).grid(row=0, column=2, padx=5) ttk.Button(driver_frame, text="自动检测", width=10, command=self.auto_detect_driver).grid(row=0, column=3, padx=5) self.driver_version_var = tk.StringVar(value="未检测") ttk.Label(driver_frame, text="驱动版本:").grid(row=1, column=0, sticky="w", padx=5) ttk.Label(driver_frame, textvariable=self.driver_version_var).grid(row=1, column=1, sticky="w") self.chrome_version_var = tk.StringVar(value="未检测") ttk.Label(driver_frame, text="Chrome版本:").grid(row=1, column=2, sticky="w", padx=5) ttk.Label(driver_frame, textvariable=self.chrome_version_var).grid(row=1, column=3, sticky="w") ttk.Button(driver_frame, text="更新驱动", command=self.update_driver).grid(row=2, column=3, padx=5, pady=5, sticky="e") # 输出设置 output_frame = ttk.LabelFrame(main_frame, text="输出设置", padding=10) output_frame.pack(fill=tk.X, pady=(0, 10)) ttk.Label(output_frame, text="保存目录:").grid(row=0, column=0, sticky="w", padx=5, pady=5) self.folder_entry = ttk.Entry(output_frame, width=50) self.folder_entry.grid(row=0, column=1, sticky="we", padx=5, pady=5) ttk.Button(output_frame, text="选择文件夹...", width=10, command=self.browse_folder).grid(row=0, column=2, padx=5) # 文件名前缀 ttk.Label(output_frame, text="文件名前缀:").grid(row=1, column=0, sticky="w", padx=5, pady=5) self.prefix_entry = ttk.Entry(output_frame, width=50) self.prefix_entry.grid(row=1, column=1, sticky="we", padx=5, pady=5) self.prefix_entry.insert(0, "screenshot") # 状态栏 status_frame = ttk.Frame(main_frame) status_frame.pack(fill=tk.X, pady=(10, 0)) self.status_var = tk.StringVar(value="就绪") ttk.Label(status_frame, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W).pack(side=tk.BOTTOM, fill=tk.X) # 进度条 self.progress_var = tk.DoubleVar(value=0.0) self.progress = ttk.Progressbar(status_frame, variable=self.progress_var, maximum=100) self.progress.pack(side=tk.BOTTOM, fill=tk.X, pady=(0, 5)) # 操作按钮 button_frame = ttk.Frame(main_frame) button_frame.pack(fill=tk.X, pady=(10, 0)) ttk.Button(button_frame, text="开始截图", command=self.start_capture).pack(side=tk.RIGHT, padx=5) ttk.Button(button_frame, text="退出", command=root.destroy).pack(side=tk.RIGHT) # 设置默认路径 self.set_default_paths() self.auto_detect_driver() def set_default_paths(self): """设置默认路径""" # 默认保存目录:用户桌面 desktop_path = os.path.join(os.path.expanduser("~"), "Desktop") self.folder_entry.delete(0, tk.END) self.folder_entry.insert(0, os.path.join(desktop_path, "网页截图")) # 尝试自动检测Chrome安装路径 chrome_path = self.detect_chrome_path() if chrome_path: driver_dir = os.path.dirname(chrome_path) driver_path = os.path.join(driver_dir, "chromedriver.exe") if os.path.exists(driver_path): self.driver_entry.delete(0, tk.END) self.driver_entry.insert(0, driver_path) def detect_chrome_path(self): """自动检测Chrome安装路径""" system = platform.system() try: if system == "Windows": # 通过注册表查找 key_path = r"SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\chrome.exe" with winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_path) as key: path, _ = winreg.QueryValueEx(key, "") return path elif system == "Darwin": # macOS return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" elif system == "Linux": # 尝试常见安装路径 paths = [ "/usr/bin/google-chrome", "/usr/bin/chromium-browser", "/usr/bin/chromium", "/snap/bin/chromium" ] for path in paths: if os.path.exists(path): return path except Exception: pass return None def browse_folder(self): """浏览选择文件夹""" folder = filedialog.askdirectory() if folder: self.folder_entry.delete(0, tk.END) self.folder_entry.insert(0, folder) def browse_driver(self): """浏览选择驱动文件""" filetypes = [("可执行文件", "*.exe" if platform.system() == "Windows" else "*")] driver_path = filedialog.askopenfilename( title="选择ChromeDriver", filetypes=filetypes ) if driver_path: self.driver_entry.delete(0, tk.END) self.driver_entry.insert(0, driver_path) self.check_driver_version() def auto_detect_driver(self): """自动检测驱动路径""" system = platform.system() common_paths = [] # Windows常见路径 if system == "Windows": common_paths = [ os.path.expandvars(r"%ProgramFiles%\Google\Chrome\Application\chromedriver.exe"), os.path.expandvars(r"%ProgramFiles(x86)%\Google\Chrome\Application\chromedriver.exe"), os.path.expandvars(r"%LOCALAPPDATA%\Google\Chrome\Application\chromedriver.exe") ] # macOS常见路径 elif system == "Darwin": common_paths = [ "/Applications/Google Chrome.app/Contents/MacOS/chromedriver", "/usr/local/bin/chromedriver", os.path.expanduser("~/bin/chromedriver") ] # Linux常见路径 elif system == "Linux": common_paths = [ "/usr/bin/chromedriver", "/usr/local/bin/chromedriver", "/snap/bin/chromedriver", os.path.expanduser("~/bin/chromedriver") ] # 检查常见路径 for path in common_paths: if os.path.exists(path): self.driver_entry.delete(0, tk.END) self.driver_entry.insert(0, path) self.check_driver_version() return # 尝试在PATH环境变量中查找 try: path = subprocess.check_output(["which", "chromedriver"], text=True).strip() if os.path.exists(path): self.driver_entry.delete(0, tk.END) self.driver_entry.insert(0, path) self.check_driver_version() return except Exception: pass messagebox.showinfo("提示", "未找到ChromeDriver, 请手动选择路径或点击'更新驱动'") def check_driver_version(self): """检查驱动和浏览器版本""" driver_path = self.driver_entry.get().strip() if not os.path.exists(driver_path): self.driver_version_var.set("无效路径") self.chrome_version_var.set("未检测") return try: # 获取驱动版本 result = subprocess.run( [driver_path, "--version"], capture_output=True, text=True, check=True ) driver_version = re.search(r"(\d+\.\d+\.\d+\.\d+)", result.stdout) if driver_version: self.driver_version_var.set(driver_version.group(1)) # 获取Chrome浏览器版本 chrome_path = self.detect_chrome_path() if chrome_path: result = subprocess.run( [chrome_path, "--version"], capture_output=True, text=True, check=True ) chrome_version = re.search(r"(\d+\.\d+\.\d+\.\d+)", result.stdout) if chrome_version: self.chrome_version_var.set(chrome_version.group(1)) except Exception as e: self.driver_version_var.set("检测失败") self.chrome_version_var.set("检测失败") def update_driver(self): """更新驱动版本""" # 获取当前Chrome主版本 chrome_version = self.chrome_version_var.get() if "未检测" in chrome_version or "失败" in chrome_version: messagebox.showerror("错误", "请先检测到有效的Chrome版本") return major_version = chrome_version.split(".")[0] threading.Thread( target=self.download_and_update_driver, args=(major_version,), daemon=True ).start() def start_capture(self): """启动截图流程""" # 验证输入 url = self.url_entry.get().strip() if not url: messagebox.showerror("错误", "请输入有效的网址") return driver_path = self.driver_entry.get().strip() if not os.path.exists(driver_path): messagebox.showerror("错误", "ChromeDriver路径无效") return # 在后台线程中执行截图 threading.Thread( target=self.capture_page, args=(url, driver_path), daemon=True ).start() def secure_capture(url): options = Options() # 关键修复配置 options.add_argument("--headless=new") options.add_argument("--disable-gpu") options.add_argument("--no-sandbox") options.add_argument("--disable-dev-shm-usage") options.add_argument("--disable-software-rasterizer") # 防止反爬虫检测 options.add_argument("--disable-blink-features=AutomationControlled") options.add_experimental_option("excludeSwitches", ["enable-automation"]) # 模拟真实浏览器 options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36") driver = webdriver.Chrome(options=options) try: driver.get(url) # 双重等待机制 WebDriverWait(driver, 15).until( EC.presence_of_element_located((By.XPATH, "//*[text()]")) ) WebDriverWait(driver, 5).until( lambda d: d.execute_script("return document.readyState === 'complete'") ) # 强制渲染动态内容 driver.execute_script(""" document.body.style.overflow = 'visible'; document.documentElement.style.height = '100%'; if(typeof echarts !== 'undefined') { echarts.getInstanceByDom(document.querySelector('.echarts')).resize(); } """) # 滚动触发渲染 driver.execute_script("window.scrollBy(0, 500)") time.sleep(0.3) # 截图前验证 if driver.execute_script("return document.body.clientHeight") < 100: driver.execute_script("document.body.style.minHeight = window.innerHeight + 'px'") # 使用PNG格式保存 return driver.get_screenshot_as_png() finally: driver.quit() def capture_page(self, url, driver_path): """执行实际截图操作""" try: self.status_var.set("正在初始化浏览器...") self.progress_var.set(10) # 配置浏览器选项 options = Options() options.add_argument("--headless=new") # 无头模式 options.add_argument("--disable-gpu") options.add_argument("--window-size=1920,1080") # 初始化WebDriver service = Service(executable_path=driver_path) driver = webdriver.Chrome(service=service, options=options) # 登录逻辑(如果有凭证) username = self.user_entry.get().strip() password = self.pass_entry.get().strip() if username and password: self.status_var.set("正在登录...") self.progress_var.set(30) driver.get(url) time.sleep(2) # 等待页面加载 # 尝试查找登录表单(实际实现需根据目标网站调整) try: driver.find_element(By.ID, "username").send_keys(username) driver.find_element(By.ID, "password").send_keys(password) driver.find_element(By.ID, "login-btn").click() time.sleep(3) # 等待登录完成 except NoSuchElementException: self.status_var.set("警告:未找到登录表单") # 搜索逻辑(如果有关键词) search_term = self.search_entry.get().strip() if search_term: self.status_var.set("正在执行搜索...") self.progress_var.set(50) try: search_box = driver.find_element(By.NAME, "q") search_box.send_keys(search_term) search_box.send_keys(Keys.RETURN) time.sleep(2) # 等待搜索结果 except NoSuchElementException: self.status_var.set("警告:未找到搜索框") # 执行截图 self.status_var.set("正在截图...") self.progress_var.set(80) timestamp = time.strftime("%Y%m%d-%H%M%S") prefix = self.prefix_entry.get().strip() or "screenshot" filename = f"{prefix}_{timestamp}.png" save_path = os.path.join(self.folder_entry.get(), filename) os.makedirs(os.path.dirname(save_path), exist_ok=True) driver.save_screenshot(save_path) self.progress_var.set(100) self.status_var.set(f"截图成功: {os.path.basename(save_path)}") except SessionNotCreatedException as e: self.status_var.set(f"驱动版本错误: {str(e)}") except WebDriverException as e: self.status_var.set(f"浏览器错误: {str(e)}") finally: try: driver.quit() except: pass # 主程序入口 if __name__ == "__main__": root = tk.Tk() app = WebScreenshotApp(root) root.mainloop() 这样的代码正确吗

我在使用selenium实现自动化的时候,出现了两个重大bug, bug1:就是我在遍历表格数据的时候,在实现判断上次用户度数和这次水表度数进行判断的功能的时候, 用户A出现某些报错后,会自动跳到下一个用户B处,但是携带的上次用户度数的值还是用户A的,这是为什么呢,请教一下各位,这是部分代码,还有日志文件。 bug2:当用户A出现某些问题后,比如说延时了,然后我设置了如果当前用户有报错,会continue,跳过当前用户,进入到下一个用户,目的是不想因为这个耽误时间。但是实际中用的时候,发现如果用户A出现了问题,他的下一个用户都会全部出错,感觉就是把错误信息带到了下一个用户,以此类推,导致写的程序效果不好,这是为什么呢?请教一下各位for index, row in dataframe.iterrows(): user_id = row.get('署名') or row.get('客户编号') or row.get('用户编号') is_change = row['是否更换'] old_base_code = row.get('拆表行度') new_quantity = row.get('新表表码') new_table_code = row.get('新表行度') or row.get('新表度数') this_handle_time = row['换表日期'] # 获取符合条件的文件路径 file_paths_list, file_paths = get_image_paths(user_id, folder_path) if len(file_paths_list) == 5 and is_change == '已更换': try: logging.info(f"正在处理用户 {user_id} 的数据...") ActionChains(driver).send_keys(Keys.F5).perform() time.sleep(5) WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.ID, 'af04599c-bd1b-420d-b5de-3f8d9e697294'))).click() time.sleep(2) input_element = driver.find_element(By.XPATH, "//div[contains(@class,'input-group f-state-editable')]/input") input_element.clear() input_element.send_keys(user_id) input_element.send_keys(Keys.ENTER) time.sleep(2) # 检查单个任务中心是否存在 if is_element_present(driver, "//div[contains(@class, 'headLine')]"): WebDriverWait(driver, 15).until(EC.element_to_be_clickable((By.CLASS_NAME, "headLine"))).click() time.sleep(5) iframe = WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.XPATH, '//iframe[contains(@id, "rtf_iframe_WF0120")]'))

from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from webdriver_manager.chrome import ChromeDriverManager import time import logging from selenium.common.exceptions import TimeoutException # 配置日志 logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') # 初始化 WebDriver def init_driver(headless=True): chrome_options = Options() if headless: chrome_options.add_argument("--headless") # 无头模式,不打开浏览器窗口 # 设置 User-Agent chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.6998.165 Safari/537.36") # 禁用图片加载 prefs = {"profile.managed_default_content_settings.images": 2} chrome_options.add_experimental_option("prefs", prefs) # 忽略 SSL 证书错误 chrome_options.add_argument('--ignore-certificate-errors') chrome_options.add_argument('--allow-insecure-localhost') # 启用 Unsafe SwiftShader chrome_options.add_argument('--enable-unsafe-swiftshader') # 使用 webdriver-manager 自动管理 chromedriver service = Service(ChromeDriverManager().install()) driver = webdriver.Chrome(service=service, options=chrome_options) logging.info("WebDriver 初始化成功") return driver # 提取视频信息 def extract_video_info(driver, url, scroll_pause_time=3, max_scroll_attempts=20): try: driver.get(url) logging.info(f"正在访问 URL: {url}") # 等待初始页面加载 try: WebDriverWait(driver, 20).until( EC.presence_of_element_located((By.ID, "root")) ) except TimeoutException: logging.error("页面加载超时") return # 滚动页面以加载更多内容 last_height = driver.exe

页面点击后多了(以流式返回对话响应 <button class="p-1 px-3 text-xs flex rounded-sm transition" type="button">默认</button> 函数调用 (Function Calling) <button class="p-1 px-3 text-xs flex rounded-sm transition" type="button">默认</button> 种子 (Seed) <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> 停止序列 (Stop Sequence) <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> 温度 (Temperature) <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> 推理努力 <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> Logit 偏置 <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> Mirostat <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> Mirostat Eta <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> Mirostat Tau <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> Top K <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> Top P <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> Min P <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> 频率惩罚 <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> 重复惩罚(Presence Penalty) <button class="p-1 px-3 text-xs flex rounded transition flex-shrink-0 outline-none" type="button">默认</button> 重复惩罚(Ollama) <button class="p-1 px-3 text-xs flex rounded transition flex-shrink-0 outline-none" type="button">默认</button> 重复最后 N 次 <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> Tfs Z <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> 上下文长度 (Ollama) <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> 批大小 (num_batch) <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> 在语境刷新时需保留的 Token 数量 <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> 最大Token数量 (num_predict) <button class="p-1 px-3 text-xs flex rounded-sm transition shrink-0 outline-hidden" type="button">默认</button> ) 运行我的代码 from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import TimeoutException, NoAlertPresentException, ElementClickInterceptedException import time class PageChangeDetector: def __init__(self, headless=False): chrome_options = Options() if headless: chrome_options.add_argument("--headless") self.driver = webdriver.Chrome(options=chrome_options) self.driver.get(login_url) self.action = ActionChains(self.driver) def login(self, email_1, password_1): try: email_input = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.NAME, 'email')) ) email_input.send_keys(email_1) password_input = WebDriverWait(self.driver, 10).until( EC.presence_of_element_located((By.NAME, 'current-password')) ) password_input.send_keys(password_1) 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 get_page_state(self): """ 获取当前页面状态 """ return { "url": self.driver.current_url, "title": self.driver.title, "window_handles": len(self.driver.window_handles), "body_text": self.driver.find_element(By.TAG_NAME, "body").text, # 截取部分内容 "page_height": self.driver.execute_script("return document.body.scrollHeight;") } def compare_states(self, before, after): """ 对比两个页面状态 """ changes = {} for key in before: if before[key] != after[key]: changes[key] = {"before": before[key], "after": after[key]} return changes def click_and_detect_changes(self, element): """ 点击元素并检测页面变化 """ # 记录点击前状态 before_state = self.get_page_state() print("点击前页面状态:", before_state) # 点击元素 try: element.click() except Exception as e: print("点击失败:", e) return # 等待页面变化(可替换为显式等待) time.sleep(1) # 处理弹窗 try: alert = self.driver.switch_to.alert print("检测到弹窗,内容为:", alert.text) alert.accept() except NoAlertPresentException: print("无弹窗") # 处理新窗口 if len(self.driver.window_handles) > 1: original_window = self.driver.window_handles[0] for window in self.driver.window_handles: if window != original_window: self.driver.switch_to.window(window) print("关闭新窗口:", self.driver.title) self.driver.close() self.driver.switch_to.window(original_window) # 记录点击后状态 after_state = self.get_page_state() print("点击后页面状态:", after_state) # 对比状态 changes = self.compare_states(before_state, after_state) if changes: print("检测到页面变化:") for key, value in changes.items(): print(f" - {key}: {value['before']} → {value['after']}") else: print("页面无变化") def safe_click(self, element): try: element.click() except ElementClickInterceptedException: print("元素被遮挡,尝试使用 JavaScript 点击") self.driver.execute_script("arguments[0].click();", element) def run_automation(self, email_1, password_1): try: login_success = self.login(email_1, password_1) if not login_success: print("登录失败,无法继续自动化操作") return print("登录成功,开始自动化操作...") #*************************************************************** detector = PageChangeDetector(self.driver) advanced_settings_button = WebDriverWait(self.driver, 10).until( EC.element_to_be_clickable((By.XPATH, "//button[@aria-label='Controls']"))) self.safe_click(advanced_settings_button) print("已点击“高级对话设置”按钮") link = WebDriverWait(self.driver, 10).until( EC.element_to_be_clickable((By.XPATH, "//div[text()='高度なパラメータ']")) ) detector.click_and_detect_changes(link) print("自动化操作完成") except Exception as e: print(f"自动化过程中发生错误: {str(e)}") finally: time.sleep(5) self.driver.quit() # 示例使用 if __name__ == "__main__": login_url = "http://10.244.1.179:3000/" email_1 = "[email protected]" password_1 = "q123456.+" automator = PageChangeDetector(headless=False) automator.run_automation(email_1, password_1) 的结果 C:\own\app\python_code\.venv\Scripts\python.exe C:\own\app\python_code\work\入职培训\打印点击\change_ele.py 登录成功,开始自动化操作... 元素被遮挡,尝试使用 JavaScript 点击 已点击“高级对话设置”按钮 点击前页面状态: {'url': 'http://10.244.1.179:3000/auth?redirect=%2F', 'title': 'NexaAI', 'window_handles': 1, 'body_text': 'Sign in to NexaAI\nメールアドレス\nパスワード\nサインイン\nアカウントをお持ちではありませんか? サインアップ\nNexaAI', 'page_height': 433} 无弹窗 点击后页面状态: {'url': 'http://10.244.1.179:3000/auth?redirect=%2F', 'title': 'NexaAI', 'window_handles': 1, 'body_text': 'Sign in to NexaAI\nメールアドレス\nパスワード\nサインイン\nアカウントをお持ちではありませんか? サインアップ\nNexaAI', 'page_height': 433} 页面无变化 自动化操作完成 Process finished with exit code 0

import time import csv from parsel import Selector from selenium import webdriver from datetime import datetime def standardize_date(date_str): date_formats = [ "Posted: %d %B, %Y", "Posted: %B %d, %Y", "Posted: %d %B", "Posted: %B %d" ] for date_format in date_formats: try: current_year = datetime.now().year date = datetime.strptime(date_str.strip(), date_format) if '%Y' not in date_format: date = date.replace(year=current_year) return date.strftime("%Y-%m-%d") except ValueError: continue return datetime.now().strftime("%Y-%m-%d") # 默认返回当前日期 def get_reviews(app_id, language="all", max_scroll=50): options = webdriver.ChromeOptions() options.add_argument("--headless") driver = webdriver.Chrome(options=options) all_reviews = [] url = f"https://steamcommunity.com/app/{app_id}/reviews/?filterLanguage={language}" driver.get(url) last_height = driver.execute_script("return document.body.scrollHeight") for _ in range(max_scroll): driver.execute_script("window.scrollTo(0, document.body.scrollHeight)") time.sleep(1.5) new_height = driver.execute_script("return document.body.scrollHeight") if new_height == last_height: break last_height = new_height s = Selector(text=driver.page_source) reviews = s.css("div.apphub_CardTextContent") for review in reviews: content = ''.join(review.xpath(".//text()").getall()).strip() content = ' '.join(content.split()) all_reviews.append({ "publish_date": standardize_date(review.css("div.date_posted::text").get()), "content": content }) driver.quit() return all_reviews if __name__ == "__main__": reviews_data = get_reviews("2358720", max_scroll=5) # 保存到CSV文件 with open('steam_reviews.csv', 'w', newline='', encoding='utf-8') as f: writer = csv.DictWriter(f, fieldnames=['publish_date', 'content']) writer.writeheader() writer.writerows(reviews_data) print(f"成功保存{len(reviews_data)}条评论")修改代码,使其爬取并保存更多评论

Traceback (most recent call last): File "D:\dev\python\pyle\onechangshi\1.py", line 63, in <module> test_login_failure() ~~~~~~~~~~~~~~~~~~^^ File "D:\dev\python\pyle\onechangshi\1.py", line 48, in test_login_failure driver.find_element(By.CLASS_NAME, "login").click() ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\pyPython—learning\.venv\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 926, in find_element return self.execute(Command.FIND_ELEMENT, {"using": by, "value": value})["value"] ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "D:\pyPython—learning\.venv\Lib\site-packages\selenium\webdriver\remote\webdriver.py", line 458, in execute self.error_handler.check_response(response) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^ File "D:\pyPython—learning\.venv\Lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 232, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".login"} (Session info: chrome=132.0.6834.84); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#nosuchelementexception Stacktrace: GetHandleVerifier [0x00007FF67F0BFBE5+28741] (No symbol) [0x00007FF67F027890] (No symbol) [0x00007FF67EEC4FDA] (No symbol) [0x00007FF67EF19322] (No symbol) [0x00007FF67EF1954C] (No symbol) [0x00007FF67EF63337] (No symbol) [0x00007FF67EF3FF4F] (No symbol) [0x00007FF67EF600B4] (No symbol) [0x00007FF67EF3FCB3] (No symbol) [0x00007FF67EF09FB3] (No symbol) [0x00007FF67EF0B331] GetHandleVerifier [0x00007FF67F3FA73D+3414941] GetHandleVerifier [0x00007FF67F40E64A+3496618] GetHandleVerifier [0x00007FF67F40413D+3454365] GetHandleVerifier [0x00007FF67F18848B+850155] (No symbol) [0x00007FF67F0337FF] (No symbol) [0x00007FF67F02F0C4] (No symbol) [0x00007FF67F02F25D] (No symbol) [0x00007FF67F01E079] BaseThreadInitThunk [0x00007FF9F86A7374+20] RtlUserThreadStart [0x00007FF9FA57CC91+33] 进程已结束,退出代码为 1

最新推荐

recommend-type

通信电子线路设计高频小信号调谐放大器-LC振荡器-高频谐振功率放大器的设计.doc

通信电子线路设计高频小信号调谐放大器-LC振荡器-高频谐振功率放大器的设计.doc
recommend-type

bitHEX-crx插件:提升cryptowat.ch与Binance平台易读性

根据给定文件信息,我们可以提炼出以下知识点: ### 标题知识点:bitHEX-crx插件 1. **插件名称解析**:该部分涉及一个名为“bitHEX”的插件,这里的“CRX”指的是Chrome扩展程序的文件格式。CRX文件是一种压缩包格式,用于在Google Chrome浏览器中安装扩展程序。这说明该插件是为Chrome浏览器设计的。 2. **插件功能定位**:标题直接表明了插件的功能特点,即调整和优化用户界面,特别是涉及到加密货币交易监控平台“cryptowat.ch”的界面颜色设置,以提升用户的视觉体验和阅读便利性。 ### 描述知识点:更改cryptowat.ch和Binance BASIC的颜色 1. **视觉优化目的**:“更改cryptowat.ch上的颜色”说明该插件的主要作用在于通过改变颜色配置,降低视觉上的饱和度,使得数字和线条的阅读变得更加轻松。 2. **平台适配性**:描述中提到的“至少现在是这样”,意味着插件在特定时间点上的功能可能仅限于调整“cryptowat.ch”的颜色设置。同时提到“和Binance BASIC以便于阅读”,表明该插件未来可能会扩展到对Binance等其他交易平台的颜色调整,提高用户在不同平台上的视觉体验。 3. **技术实现细节**:描述中还暗示了插件目前未能改变“交易平台画布上的饱和色”,表明该插件目前可能只影响了网页上的某些特定元素,而非全部。作者表示这一功能将在后续版本中实现。 ### 标签知识点:扩展程序 1. **软件分类**:标签“扩展程序”准确地揭示了bitHEX-crx的软件类型。扩展程序是可安装在浏览器上的小型软件包,用以增强或改变浏览器的默认功能。Chrome扩展程序特别流行于改变和自定义用户的网络浏览体验。 2. **使用环境**:该标签还表明该插件是专门为使用Google Chrome浏览器的用户设计的。Chrome浏览器作为全球使用最多的浏览器之一,有大量的用户基础,因此这类扩展程序的开发对提高用户体验具有重要意义。 ### 压缩包子文件的文件名称列表:bitHEX.crx 1. **文件格式说明**:从文件列表中我们得知该扩展程序的文件名是“bitHEX.crx”。CRX文件格式是专为Chrome浏览器扩展而设计,用户可以直接从Chrome网上应用店下载或通过开发者提供的URL安装CRX文件。 2. **安装方法**:用户获取该CRX文件后,可以通过简单的拖拽操作或在Chrome浏览器的“扩展程序”页面,启用“开发者模式”,然后点击“加载已解压的扩展程序”来安装该插件。 通过以上知识点的分析,我们可以得出,bitHEX-crx插件是一个针对加密货币交易监控平台用户界面的视觉优化Chrome扩展程序。它通过调整颜色设置来改善用户在使用特定金融交易平台时的视觉体验,目的是让数字和线条的显示更加清晰,以便用户能够舒适、高效地进行市场监控和交易操作。随着开发的推进,该插件未来可能会添加更多平台的颜色调整支持。
recommend-type

UnityML-Agents:相机使用与Python交互教程

### Unity ML-Agents:相机使用与Python交互教程 本文将深入探讨在Unity中为智能体添加相机、查看相机视角以及使用Python与Unity ML-Agents进行交互的详细过程。 #### 为智能体添加新相机 在Unity中,为智能体添加新相机可按以下步骤操作: 1. 使用层级面板,创建一个新相机作为“Balancing Ball”对象(智能体和球的父对象)的子对象。 2. 将新相机重命名为有意义的名称,如“Agent Camera”。 3. 调整新相机的位置,使其指向智能体和球。 4. 在层级面板中选择智能体,使用“Add Component”按钮添加“Camer
recommend-type

INA141仿真

INA141 是一款由 Texas Instruments(TI)生产的电流检测放大器,常用于高侧电流检测,具有较宽的共模电压范围和高精度的增益特性。对 INA141 芯片进行电路仿真时,通常可以使用主流的电路仿真工具如 **Pspice** 或 **Tina**,它们支持对电流检测电路的建模与分析。 ### 仿真方法 在进行 INA141 的电路仿真时,需构建一个完整的电流检测电路模型,包括输入端的采样电阻、负载、电源以及 INA141 的外围电路配置。以下是一个典型的仿真流程: 1. **搭建主电路模型**:将 INA141 的输入端连接至采样电阻两端,该电阻串联在电源与负载之间。
recommend-type

揭露不当行为:UT-Austin教授监控Chrome扩展

根据提供的文件信息,我们可以提炼出以下几点与“Professor Watch-crx插件”相关的知识点: 1. 插件功能定位: “Professor Watch-crx插件”是一款专为德克萨斯大学奥斯汀分校(UT-Austin)定制的Chrome扩展程序,旨在帮助学生和教师了解哪些教授曾经侵犯过学校性行为不当政策。该插件将相关信息整合到学校的课程目录中,以便用户在选课时能够掌握教师的相关背景信息。 2. 插件的作用和重要性: 插件提供了一种透明化的方式,使学生在选择课程和教授时能够做出知情的决定。在某些情况下,教授的不当行为可能会对学生的教育体验产生负面影响,因此该插件帮助用户避免潜在的风险。 3. 插件信息展示方式: 插件通过颜色编码来传达信息,具体如下: - 红色:表示UT的标题IX办公室已经确认某教授违反了性行为不当政策。 - 橙色:表示有主要媒体渠道报告了对某教授的不当行为指控,但截至2020年4月,UT的标题IX办公室尚未对此做出回应或提供相关信息。 4. 插件的数据来源和透明度: 插件中包含的信息来自于学生和教师的活动,并经过了一定的公开披露。该插件并非由德克萨斯大学创建或批准,它将用户引向一个外部网站(https://utmiscondone.wordpress.com/about-the-data/),以获取更多可公开获得的信息。 5. 插件的标签: 根据文件提供的信息,这款插件的标签是“扩展程序”(Extension),说明它属于Chrome浏览器的附加组件类别。 6. 插件文件名称: 插件的压缩包子文件名是“Professor_Watch.crx”,这是一个Chrome扩展程序的常用文件格式,用户可以通过Chrome浏览器直接下载并安装该插件。 7. 相关技术知识: - Chrome扩展程序开发涉及HTML、CSS和JavaScript等Web开发技术,以及Chrome扩展API。 - Chrome扩展程序可以利用各种浏览器提供的接口,如标签页、书签、历史记录、下载项和搜索等进行操作。 - 扩展程序的安装包为.crx文件,它是Chrome浏览器专用的打包格式,其中包含了扩展程序的所有资源和文件。 8. 法律与伦理考量: 使用此类插件可能会触及隐私权和诽谤等法律问题。开发者和用户需要注意不要侵犯他人名誉权,同时也要确保收集和发布的数据是准确和合法的。 9. 学术自由和言论自由的边界: 插件可能引发有关学术自由和言论自由边界的讨论。一方面,学生和教师需要在一个安全和支持的环境中学习和工作,另一方面,这也可能带来对教师声誉的不当影响。 通过这些知识点,我们可以看出“Professor Watch-crx插件”是一个旨在提高教育环境透明度和安全性的工具,它也引发了一系列关于个人隐私、信息准确性、法律义务和社会伦理的深入讨论。
recommend-type

UnityML-Agents合作学习与相机传感器应用指南

### Unity ML-Agents 合作学习与相机传感器应用指南 #### 合作学习环境搭建 在构建合作学习环境时,我们需要完成一系列的代码编写和配置工作。首先是环境管理器脚本部分,它的主要功能是重置定时器、旋转整个区域、为代理和方块分配随机位置和旋转,并将方块设置为活动状态。以下是相关代码: ```csharp item.BlockTransform.transform.SetPositionAndRotation(pos,rot); item.RigidBody.velocity = Vector3.zero; item.RigidBody.angularVelocity = Vec
recommend-type

edge下载linux

在Linux系统上下载和安装Microsoft Edge浏览器可以通过多种方式实现。以下是最常见的几种方法: ### 1. 从 Microsoft Edge Insider 网站下载安装包 Microsoft Edge Insider 网站提供了适用于 Linux 的 `.deb` 和 `.rpm` 安装包,用户可以直接访问该网站下载[^1]。这个方法的优势在于系统可以自动更新浏览器版本。 - 访问地址:[https://www.microsoftedgeinsider.com/zh-cn/download/](https://www.microsoftedgeinsider.com/zh
recommend-type

揭秘快速赚钱系统-免费使用CRX插件

根据给定的文件信息,可以提取以下知识点: 1. 插件类型:标题中提到的是一个名为 "Free Access To Money Making System" 的插件,且文件扩展名为 .crx,表明这是一个专为Google Chrome浏览器设计的扩展程序(也称为插件或扩展)。CRX文件是Chrome扩展程序的官方格式,允许用户通过Chrome Web Store或者直接通过下载安装到浏览器中。 2. 功能描述:从标题和描述可以看出,该插件可能被设计用于通过某种形式帮助用户赚钱。描述中提到“免费使用赚钱系统”,以及“比以往任何时候都更快地产生销售和佣金”,暗示了该插件可能涉及营销、广告、会员联盟或者其它形式的电子商务功能,用户可能可以通过推广产品或服务来赚取收益。 3. 语言信息:描述中提到插件的语言为English,即英语,说明该插件的用户界面和文档可能主要以英语呈现。 4. 安全性和合法性问题:在进行讨论时,需要指出网络上存在着许多声称能够帮助用户快速赚钱的程序,其中不少是诈骗或不合法的。关于这个特定插件,没有足够的信息来评价其合法性或安全性,因此用户在下载和使用此类插件时应保持警惕。合法赚钱系统通常要求用户付出真正的劳动或者提供有价值的服务,而不是依靠简单地安装软件来实现。 5. Chrome扩展程序的特点:Chrome扩展程序通常可以通过Chrome浏览器右上角的菜单访问,用户可以在"更多工具"下找到"扩展程序"选项来管理已安装的扩展。Chrome扩展允许用户对浏览器进行个性化配置,增强功能,如广告拦截、密码管理、视频下载等。扩展程序的来源可能包括Chrome Web Store或者直接从开发者提供的网站下载。 6. 扩展程序文件结构:文件名称 "Free_Access_To_Money_Making_System.crx" 反映了该扩展程序的文件结构。CRX文件通常为ZIP格式压缩包,用户可以通过更改文件扩展名从 .crx 到 .zip 来解压文件内容,以便查看其内部结构,包括插件的源代码、资源文件、插件的权限声明等。 7. 插件权限和隐私:在安装任何扩展程序时,都应该关注其权限请求。根据插件的功能,它可能要求访问用户的浏览数据、读取和修改浏览器历史记录、管理下载等。用户应仔细阅读并理解这些权限,以确保个人隐私和数据的安全。 综上,标题和描述中的知识点围绕一个名为 "Free Access To Money Making System" 的Chrome扩展程序展开,它可能具有帮助用户进行网络赚钱的特性。然而,用户在下载和使用该扩展程序之前,应该对其合法性和安全性进行充分的评估和审查。此外,Chrome扩展程序的管理和使用也是重要的知识点之一,包括对扩展程序文件结构和权限的理解,以及如何安全地安装和维护扩展程序。
recommend-type

高级模仿学习与课程学习指南

### 高级模仿学习与课程学习指南 在机器学习领域,高级模仿学习和课程学习是提升模型性能和效率的重要方法。下面将详细介绍如何使用GAIL(生成对抗模仿学习)进行训练,以及课程学习的概念和应用。 #### 1. 使用GAIL进行训练 ##### 1.1 准备工作 - **重命名场景**:将复制的场景重命名为“GAIL”或类似名称。 - **添加关键对象**: 1. 在项目层次结构中添加一个新的立方体。 2. 将这个立方体重命名为“key”。 ##### 1.2 修改代理代码 - **打开代码文件**:打开`Roller.cs`文件。 - **添加成员变量**:在类中添加以下
recommend-type

CSP-J2024初赛讲解

CSP-J(Certified Software Professional - Junior)是面向青少年的信息学奥林匹克竞赛,由中国计算机学会(CCF)主办,旨在选拔和培养具有潜力的编程人才。2024年的CSP-J初赛内容和备考策略可以从以下几个方面进行详细解析: ### 一、考试内容概述 CSP-J初赛主要考察学生的计算机基础知识、程序设计能力和算法思维。考试内容通常包括以下几个方面: 1. **计算机基础知识**:包括计算机组成原理、操作系统基础、网络基础、数据结构基础等[^1]。 2. **编程语言**:CSP-J主要使用C++、Python或Pascal作为编程语言,考生需要熟