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 点击

Selenium 等待可点击 - 元素点击被拦截问题

ElementClickInterceptedException:元素点击被拦截:[重复]

python selenium drag_and_drop()和drag_and_drop_with_offset()怎么使用?

Selenium with Python中文翻译文档

Selenium with Python中文翻译文档