Python with Selenium:点击拦截并找到不同的跨度类
Posted
技术标签:
【中文标题】Python with Selenium:点击拦截并找到不同的跨度类【英文标题】:Python with Selenium: Click intercepted and finding different span classes 【发布时间】:2019-11-19 09:03:01 【问题描述】:我正在尝试编写一个像这样工作的程序:
-
转到主页
单击列表中的第一项(所有项均以“item-”开头),进入下一页。
找到一个带有“A”的按钮并点击它。
找到一个“确认”按钮并点击它。
返回,对第 2 项、第 3 项等进行相同操作。
我有两个问题。首先,上面有“A”的按钮,有时比简单的“A”有更多的文字,例如。 “A”和“123”脚注。我对 html 不太了解,但这会导致不同的 span 和 div 类:
<div class="selectOne">
<span class="selectObject-no-footnote">A</span>
</div>
<div class="selectOne-with-footnote">
<span class="selectObject">A</span>
<span class="selectFootnote">
<span>123</span>
</span>
</div>
它们从不在同一个页面上,但在我的解决方案中,“A”按钮并不总是被按下。很难说是因为我的解决方案不正确还是来自第二个问题。通常(这是随机的)当我进入带有按钮的页面时,一些横幅从页面顶部滚落,整个网站以一种我的“确认”按钮看不见的方式移动。我解决它的方法是每次向下滚动网站,然后才开始寻找按钮。那么横幅是否滚下并不重要,因为在这两种情况下,按钮“A”和“确认”都是可见的。但是,我仍然没有 100% 的准确率,有时我会得到 click intercepted
异常。我的代码:
i=0
a=1
while True:
WebDriverWait(driver, 1).until(EC.element_to_be_clickable((By.XPATH, "//*[starts-with(@id, 'item-')]")))
items = driver.find_elements_by_xpath("//*[starts-with(@id, 'item-')]")
try:
items[i].click()
try:
try:
driver.execute_script("window.scrollTo(0, 250)")
WebDriverWait(driver, 1).until(EC.element_to_be_clickable((By.XPATH,"//span[@class='selectObject-no-footnote'][contains(text(),'A')]")))
driver.find_element_by_xpath("//span[@class='selectObject-no-footnote'][contains(text(),'A')]").click()
except Exception as e:
a = 0
print(e)
if a==0:
driver.execute_script("window.scrollTo(0, 250)")
WebDriverWait(driver, 1).until(EC.element_to_be_clickable((By.XPATH, "//span[@class='selectObject'][contains(text(),'A')]")))
driver.find_element_by_xpath("//span[@class='selectObject'][contains(text(),'A')]").click()
a=1
WebDriverWait(driver,1).until(EC.element_to_be_clickable((By.ID, 'confirm')))
driver.find_element_by_id('confirm').click()
except Exception as e:
print(e)
i += 1
driver.back()
except IndexError:
print(items)
print(i)
break
是否有其他工具可以做到这一点,而不必担心元素被某物覆盖或超出窗口? (废话?)
【问题讨论】:
【参考方案1】:整体逻辑是正确的。我建议进行两个更改,(这是在 JAVA 中)
1) 使用以下 xpath 找到带有文本 A 的按钮。这应该适用于两种情况(A 或 A123)
WebElement button = driver.findElement(By.xpath("//span[contains(@class,'selectObject')][contains(text(),'A')]");
button.click();
2) 您可以向下滚动到该元素并等待上述元素在页面上可见且可点击。
((javascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", button);
【讨论】:
在 1) 你没有指定你正在寻找 A,并且有多个按钮具有相同的 span 类名,这就是我使用 contains('A') 的原因.此外,您的解决方案不会慢得多,因为它必须遍历所有跨度类,而不仅仅是通过我指定的那些,还是不明显?至于2),我如何向下滚动到特定元素? 更新了 xpath。它可能会更慢,但几乎不明显。我还添加了向下滚动到页面上特定元素的代码。 我相信它现在点击了 100% 的按钮,但是在几个第一个按钮之后它运行得非常慢(比如 5 秒向下滚动到 A 按钮并点击它)。当我使用 window.scrollTo 向下滚动时,它运行良好,直到出现崩溃。还有为什么 Selenium 可以向右滚动到元素,即使它在窗口之外,但不能点击它? @NotStudent 您可以点击该元素,但如果它不在视口中则不能保证。我不确定为什么向下滚动需要 5 秒。您的脚本是否正在等待页面文档完全加载?如果此答案达到目的,请接受。谢谢!以上是关于Python with Selenium:点击拦截并找到不同的跨度类的主要内容,如果未能解决你的问题,请参考以下文章
ElementClickInterceptedException:消息:元素点击被拦截:元素 <label> 不能使用 Selenium 和 Python 点击
ElementClickInterceptedException:元素点击被拦截:[重复]
python selenium drag_and_drop()和drag_and_drop_with_offset()怎么使用?