Python Selenium在Supreme网站通过ID定位元素后send_keys报错
嘿,我之前也踩过类似Selenium和动态页面交互的坑,咱们一步步拆解解决你的问题:
首先看你碰到的错误:unknown error: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element',这个错误的本质是你用find_element_by_id拿到的元素已经不是有效的DOM元素了——要么是页面动态渲染时把这个元素替换掉了,要么是元素还没完全加载好,WebDriver就拿到了一个无效的引用。
而用xpath能运行但速度慢,是因为xpath是遍历整个DOM树找元素,它可能在元素完全渲染完成后才定位到目标,所以没报错,但效率自然比浏览器原生支持的id查找低很多。
下面是几个针对性的解决方案,按优先级推荐:
1. 先修复ChromeDriver和Chrome的版本兼容问题
这大概率是核心诱因!你的Chrome版本是66.0.3359.181,但ChromeDriver用的是2.35——查版本对应表就知道,Chrome 66需要搭配ChromeDriver 2.38及以上版本(2.35仅支持Chrome 62-64)。版本不兼容会导致各种莫名其妙的DOM操作错误,先把这个问题解决,很多奇怪的bug都会消失。
你可以下载对应Chrome版本的ChromeDriver,替换掉当前的驱动即可。
2. 用显式等待确保元素完全可交互
Supreme的页面是动态加载的,有时候元素虽然已经出现在DOM里,但还没准备好接收输入,直接调用send_keys就会报错。这时候用显式等待等元素可交互后再操作就很关键:
from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC d = webdriver.Chrome() # 添加商品到购物车 d.get('http://www.supremenewyork.com/shop/tops-sweaters/vxdau6b3t/km1pzdca3') d.find_element_by_name('commit').click() # 不要直接get结账页面,建议通过购物车入口进入,保持会话状态更稳定 d.find_element_by_css_selector('a.cart-button').click() d.find_element_by_link_text('checkout now').click() # 显式等待元素可交互,最长等待10秒 name_box = WebDriverWait(d, 10).until( EC.element_to_be_clickable((By.ID, 'order_billing_name')) ) name_box.send_keys('name goes here')
这里顺便调整了进入结账页面的方式——直接用get跳转可能会丢失购物车的会话状态,通过点击购物车和结账按钮的方式更贴近真实用户操作,稳定性更高。
3. 用JavaScript注入绕过send_keys的问题
如果上面的方法还是不行,可以试试用JavaScript直接设置输入框的值,绕过Selenium的send_keys方法:
name_box = d.find_element_by_id('order_billing_name') d.execute_script("arguments[0].value = 'name goes here';", name_box)
这种方式不依赖Selenium的元素交互逻辑,直接操作DOM,有时候能解决一些奇怪的输入问题。
为什么xpath能运行但速度慢?
xpath是通过遍历整个DOM树来匹配元素的,浏览器没有原生的xpath快速查找支持,所以速度会比id查找慢很多。而它能运行的原因可能是xpath查找的时机更晚,等到元素完全渲染好之后才找到有效的元素,所以没触发错误,但效率肯定不如id查找。
内容的提问来源于stack exchange,提问作者LagMaster163

