尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

【PYTHON】使用Selenium + ChromeDriver以及XPATH语法

【PYTHON】使用Selenium + ChromeDriver以及XPATH语法 【PYTHON】使用Selenium ChromeDriver以及XPATH语法查看chrome版本手动下载驱动代码如何配置监听地址0.0.0.0无效XPATH语法一、 基础路径选择二、 属性与文本过滤谓语1. 属性过滤使用 符号2. 文本内容过滤三、 模糊匹配与高级函数四、 节点关系与轴Axes五、 按位置/次序选择六、 Python/Selenium 实战代码示例️ XPath 调试技巧七、 svg的选择特例1. //div[contains(class,form)]//label[normalize-space(text())密码]2. //div[classform][.//label[text()密码]]3. //div[classform][./label[text()密码]] 核心区别总结查看chrome版本reg query HKEY_CURRENT_USER\Software\Google\Chrome\BLBeacon /v version手动下载驱动120.0.6099.109需要换成自己的https://storage.googleapis.com/chrome-for-testing-public/120.0.6099.109/win64/chromedriver-win64.zip代码importsubprocessimporttimefromseleniumimportwebdriver# Step 1: 以远程调试模式启动 Chrome命令行执行# Windows: C:\Program Files\Google\Chrome\Application\chrome.exe --remote-debugging-address0.0.0.0 --remote-debugging-port9222 --user-data-dirC:\chrome_debug_profile# macOS: /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port9222 --user-data-dir/tmp/chrome_debug# Step 2: Python 连接到已有实例optionswebdriver.ChromeOptions()options.add_experimental_option(debuggerAddress,127.0.0.1:9222)driverwebdriver.Chrome(optionsoptions)print(f已连接到现有浏览器当前页面:{driver.title})# 此时所有 Cookie、登录状态均保留fromseleniumimportwebdriverfromselenium.webdriver.chrome.serviceimportServicefromselenium.webdriver.common.byimportByfromselenium.webdriver.support.uiimportWebDriverWaitfromselenium.webdriver.supportimportexpected_conditionsasECfromwebdriver_manager.chromeimportChromeDriverManager# 1. 配置 Chrome 选项optionswebdriver.ChromeOptions()# ✅ 关键配置脚本结束后保持浏览器打开不自动关闭options.add_experimental_option(detach,True)options.add_argument(--start-maximized)# 最大化窗口options.add_argument(--disable-blink-featuresAutomationControlled)# 降低被检测概率# 2. 初始化驱动自动下载/匹配 ChromeDriverserviceService(executable_pathrD:\pythonauto\chromeDriver\driver\chromedriver.exe)driverwebdriver.Chrome(serviceservice,optionsoptions)# 常用配置try:# 3. 打开百度driver.get(https://www.baidu.com)print(✅ 已打开百度)# 4. 等待搜索框加载并输入手机search_boxWebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,chat-textarea)))search_box.clear()search_box.send_keys(手机)print(✅ 已输入关键词手机)# 5. 点击百度一下按钮submit_btnWebDriverWait(driver,10).until(EC.element_to_be_clickable((By.ID,chat-submit-button)))submit_btn.click()print(✅ 已点击搜索请在浏览器中查看结果)# 6. ✅ 阻塞等待用户手动输入 q 退出print(\n*40)whileTrue:user_inputinput( 按 q 并回车退出浏览器: ).strip().lower()ifuser_inputq:breakprint(❌ 输入无效请输入 q 退出)finally:# 7. 用户确认后关闭浏览器并释放资源print( 正在关闭浏览器...)driver.quit()print(✅ 浏览器已安全关闭)如何配置监听地址0.0.0.0无效windows shell执行# 让 Chrome 正常监听 127.0.0.1:9223不需要改任何参数 # 然后添加系统级端口转发外部访问 0.0.0.0:9223 → 127.0.0.1:9223 netsh interface portproxy add v4tov4 listenport9223 listenaddress0.0.0.0 connectport9223 connectaddress127.0.0.1 # 验证转发规则已生效 netsh interface portproxy show all # 验证外部可访问 netstat -ano | findstr :9223 # 应同时看到 0.0.0.0:9223 LISTENING 和 127.0.0.1:9223 LISTENING #删除规则 #netsh interface portproxy delete v4tov4 listenport9223 listenaddress0.0.0.0XPATH语法一、 基础路径选择路径表达式用于描述目标节点与文档根节点的关系分为绝对路径和相对路径。语法说明示例/绝对路径从根节点开始一层层往下找。/html/body/div/form/input//相对路径从任意节点开始忽略前面的层级查找所有匹配的后代元素。//input或//div//input.选取当前节点。...选取当前节点的父节点。//input/..选取 input 的父节点 最佳实践在自动化测试中强烈建议使用相对路径 (//)。绝对路径一旦前端页面结构发生微调如多嵌套一层 div定位就会立刻失效。二、 属性与文本过滤谓语使用方括号[]作为谓语Predicate可以根据属性值或文本内容精确筛选节点。1. 属性过滤使用符号语法说明示例[属性名值]精确匹配属性值//input[idusername][属性名]仅判断是否拥有该属性//*[multiple][attr1 and attr2]同时满足多个属性//input[typetext and nameemail]2. 文本内容过滤语法说明示例text()文本精确匹配文本内容//span[text()下一步]normalize-space(.)文本去除首尾空白、合并中间空格后精确匹配最稳健。//button[normalize-space(.)确认]三、 模糊匹配与高级函数当属性值或文本是动态生成、包含空格或只有部分固定时使用以下函数。函数说明示例contains()包含匹配最常用//label[contains(class,btn)]//span[contains(text(),下一步)]starts-with()前缀匹配//label[starts-with(class,btn)]ends-with()后缀匹配XPath 2.0部分浏览器支持//input[ends-with(id,_input)]string-length()字符串长度判断//input[string-length(value)5]四、 节点关系与轴Axes用于处理复杂的 DOM 结构如父子、兄弟节点定位。轴名称说明示例parent::选取父节点//input[idchild]/parent::divchild::选取直接子元素//ul/child::li(等同于//ul/li)descendant::选取所有后代元素//ul/descendant::input(等同于//ul//input)ancestor::选取所有先辈节点父、祖父等//input/ancestor::formfollowing-sibling::选取当前节点之后的所有同级兄弟节点//label[text()标题]/following-sibling::inputpreceding-sibling::选取当前节点之前的所有同级兄弟节点//input[typesubmit]/preceding-sibling::button五、 按位置/次序选择当页面有多个相同结构的元素时可以通过索引定位。⚠️ 注意XPath 的索引是从 1 开始的不是从 0 开始语法说明示例[n]选取某类型的第 n 个子元素//ul/li选取第二个 li[last()]选取最后一个元素//p[last()][last()-n]选取倒数第 n1 个元素//div/p[last()-2][position()n]选取前 n 个元素//option[position()3]六、 Python/Selenium 实战代码示例结合 Selenium 的find_element方法以下是常见场景的代码实现fromselenium.webdriver.common.byimportBy# 1. 基础属性定位driver.find_element(By.XPATH,//input[idusername])# 2. 多属性组合定位 (AND 逻辑)driver.find_element(By.XPATH,//input[typetext and nameemail])# 3. 模糊匹配 class (防止 class 动态拼接导致失效)driver.find_element(By.XPATH,//button[contains(class, aui-button--primary)])# 4. 通过文本定位并处理空白字符driver.find_element(By.XPATH,//button[normalize-space(text())确认])# 5. 相对位置定位找到 label 后的第一个 input 兄弟节点driver.find_element(By.XPATH,//label[text()标题]/following-sibling::input)[[source_group_web_16]]# 6. 向上查找祖先节点driver.find_element(By.XPATH,//input[idchild]/ancestor::div[classform-item])# 7. 获取多个元素 (返回列表)elementsdriver.find_elements(By.XPATH,//ul/li[classitem])️ XPath 调试技巧在编写代码前强烈建议先在浏览器中验证表达式按F12打开浏览器开发者工具。切换到Elements面板按Ctrl F(或Cmd F) 调出搜索框。在搜索框中直接输入你的 XPath 表达式浏览器会高亮显示匹配到的元素及数量。也可以在Console面板输入$x(//你的xpath表达式)进行验证。七、 svg的选择比如当鼠标移动到某一元素后svg才显示然后点击需要使用*[name()svg]来选择svg全部代码elementsdriver.find_elements(By.XPATH,//label[forcategoryDesc]//following-sibling::div//input/parent::div/span/span/*[name()svg][1])ActionChains(driver).move_to_element(elements[0]).perform()elements[0].click()特例//div[contains(class,‘form’)]//label[normalize-space(text())‘密码’]//div[class‘form’][.//label[text()‘密码’]]//div[class‘form’][./label[text()‘密码’]]三者的区别我们假设页面上有如下 HTML 结构!-- 结构 A嵌套了一层 div --divclassform is-activedivclassform-itemlabel密码/label/div/div!-- 结构 Blabel 直接在 form 下 --divclassformlabel密码/label/div下面为你逐一拆解它们的区别1.//div[contains(class,form)]//label[normalize-space(text())密码]最终返回的是label元素class 匹配使用contains()能匹配到结构 A 中classform is-active的 div。层级匹配使用了//label双斜杠能穿透中间的div classform-item找到任意层级的 label。文本匹配使用了normalize-space()能自动去除label 密码 /label中的前后空格。总结这是最健壮、最推荐的写法。它容错率最高能应对动态 class、深层嵌套和格式化空白。2.//div[classform][.//label[text()密码]]最终返回的是div classform容器元素class 匹配使用精确匹配不能匹配结构 A因为多了is-active只能匹配结构 B。层级匹配谓词内使用了.//label带点的//能穿透中间层级只要在这个 div 内部任意位置有“密码” label 即可。文本匹配使用了text()密码如果 label 带有空格如label 密码 /label会匹配失败。总结这是一个**“通过内部特征来锁定外部容器”**的写法。它的致命弱点是 class 精确匹配和文本精确匹配在实际自动化中极易因为前端微调而失效。3.//div[classform][./label[text()密码]]最终返回的是div classform容器元素class 匹配同样是精确匹配只能匹配结构 B。层级匹配谓词内使用了./label单斜杠/只能查找 div 的直接子元素。如果 label 被包裹在div classform-item里如结构 A会直接匹配失败。文本匹配同样是精确匹配遇到空格会失败。总结这是最脆弱的写法。它要求 div 和 label 必须是严格的父子关系且 class 和文本不能有任何多余字符。 核心区别总结特性表达式 1 (contains//normalize)表达式 2 (.//text)表达式 3 (./text)返回目标label元素div容器div容器兼容动态 class✅ 兼容❌ 不兼容❌ 不兼容兼容深层嵌套✅ 兼容✅ 兼容❌仅限直接子元素兼容文本含空格✅ 兼容❌ 不兼容❌ 不兼容实战推荐度⭐⭐⭐⭐⭐ (极高)⭐⭐ (极低)⭐ (极低)
返回列表