【问题标题】:Why selenium click by JS is not always performed?为什么不总是执行 JS 的 selenium click?
【发布时间】:2021-03-11 15:26:13
【问题描述】:

我一直在尝试创建一个 python 脚本来点击谷歌地图中的元素。 我通过JS实现了点击功能。在单击之前,我确保驱动程序使用WebDriverWait 和预期条件等到元素可单击。

但是,点击并不总是执行,当不执行时,不会引发错误。 我不知道为什么这是随机工作。

这是我的代码:

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://www.google.fr/maps/search/scooter+moto+v%C3%A9lo/@48.8455505,2.3772185,14z')
driver.switch_to.frame(WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//iframe[contains(@src, 'consent.google.com')]")))) 
driver.find_element_by_xpath('//*[@id="introAgreeButton"]/span/span').click()

element = WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,'/html/body/jsl/div[3]/div[9]/div[8]/div/div[1]/div/div/div[4]/div[1]/div[1]')))
driver.execute_script("arguments[0].click();", element)

如果有人能帮忙,我会很高兴

【问题讨论】:

  • 它有效,你面临什么问题,

标签: javascript python selenium selenium-webdriver selenium-chromedriver


【解决方案1】:

对于 Selenium 中的任何问题,如果没有看到实际的测试,通常不会有明显的答案。

但是,在我看来有问题的一件事是您的选择器:/html/body/jsl/div[3]/div[9]/div[8]/div/div[1]/div/div/div[4]/div[1]/div[1]。这是一个非常脆弱的选择器,因为它依赖于大量位置参数和元素嵌套方式的特定结构,特别是因为我假设您不控制 Google 地图。如果 div 在页面上的显示方式与该顺序有任何不同,则它不会起作用。

我的预感是你的等待是在某个时候找到那个元素,但这不是你想象的那样,因为 DOM 正在改变。根据 DOM 的状态,选择器可能是您想要的,也可能不是。

不要依赖选择器的完整 DOM 结构/层次结构

将该选择器更新为更具体且不依赖于元素顺序的选择器。我总是不鼓励人们使用产生类似选择器的 xpath 生成器。相反,请查看是否存在特定于您要与之交互的元素的类、id 或属性。这也可能是父母身上的东西。有很多方法可以在不依赖严格的 HTML 结构/位置的情况下使 xpath 和 css 工作。我推荐这个有趣/方便的游戏来了解更多关于 CSS 选择器的信息:https://flukeout.github.io/

您示例中的第一个选择器在这方面要好得多。

如果您可以提供您尝试与之交互的 Google 地图上的元素的屏幕截图,我可以为您提供更好的示例。

【讨论】:

    【解决方案2】:
    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
    import time
    driver = webdriver.Chrome()
    driver.get(
        'https://www.google.fr/maps/search/scooter+moto+v%C3%A9lo/@48.8455505,2.3772185,14z')
    driver.switch_to.frame(WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
        (By.XPATH, "//iframe[contains(@src, 'consent.google.com')]"))))
    driver.find_element_by_xpath('//*[@id="introAgreeButton"]/span/span').click()
    
    element = WebDriverWait(driver, 10).until(EC.presence_of_element_located
    ((By.XPATH, '(//div[@class="section-layout section-scrollbox scrollable-y scrollable-show section-layout-flex-vertical"]/div/div[not(@class)]/div)[2]')))
    
    element.click()
    input()
    

    您的代码工作正常,等待 isvisible 和 isenabled 的可点击检查。如上答案而不是使用绝对 xpath ,通过找到一个唯一的父级来使用相对 xpath

    另一种做法是:

    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
    import time
    driver = webdriver.Chrome()
    driver.get(
        'https://www.google.fr/maps/search/scooter+moto+v%C3%A9lo/@48.8455505,2.3772185,14z')
    driver.switch_to.frame(WebDriverWait(driver, 10).until(EC.element_to_be_clickable(
        (By.XPATH, "//iframe[contains(@src, 'consent.google.com')]"))))
    driver.find_element_by_xpath('//*[@id="introAgreeButton"]/span/span').click()
    
    element = WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located
    ((By.XPATH, '//div[@class="section-layout section-scrollbox scrollable-y scrollable-show section-layout-flex-vertical"]/div/div[not(@class)]/div')))
    
    element[2].click()
    input()
    

    【讨论】:

    • 您好,感谢您的回答,有效地使用相对 xpath 您的代码可以正常工作,但是我想使用似乎不适用于相对 xpath 的 JS 执行点击功能
    • 感谢它有效地工作但是我不确定你是如何构建与点击的元素相对应的相对 xpath,想象我想点击谷歌地图上显示的结果中的第二张卡片而不是第一个你会怎么做,我知道这似乎有点愚蠢,但我想不通
    • (//div[@class="section-layout sectio n-scrollbox scrollable-y scrollable-show section-layout-flex-vertical"]/div/div) 把这个改成 2跨度>
    • 查看更新后的答案,如果有帮助请点击对勾接受答案
    • 对不起,第一个和第二个解决方案都不适用于我的电脑
    猜你喜欢
    • 1970-01-01
    • 2019-04-15
    • 2013-09-03
    • 2021-10-12
    • 2017-05-10
    • 1970-01-01
    • 2019-06-01
    • 2021-01-12
    • 2018-10-07
    相关资源
    最近更新 更多