我一直在尝试创建一个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)
如果有人能帮助,我会很高兴
对于Selenium中的任何问题,如果没有看到测试的运行,通常不会有明显的答案。
然而,有一件事在我看来有问题,那就是这里的选择器:/html/body/jsl/div[3]/div[9]/div[8]/div/div[1]/div/div/div[4]/div[1]/div[1]
。这是一个非常脆弱的选择器,因为它依赖于大量的位置参数和元素嵌套的特定结构,尤其是因为我假设你不能控制谷歌地图。如果div在页面上的显示方式与该顺序有任何不同,那就行不通了。
我的直觉是,你的等待是在某个时候找到那个元素,但它并不是你想象的那样,因为DOM正在改变。根据DOM的状态,选择器可能是您想要的,也可能不是。
选择器不依赖于完整的DOM结构/层次结构
更新该选择器,使其更加具体,并且不依赖于元素的顺序。我总是不鼓励人们使用产生类似选择器的xpath生成器。相反,查看是否存在特定于要与之交互的元素的类、id或属性。这也可能是父母的问题。有很多方法可以使xpath和css在不依赖于严格的HTML结构/位置的情况下工作。我推荐这个有趣/方便的游戏来学习更多关于css选择器的信息:https://flukeout.github.io/
在这方面,示例中的第一个选择器要好得多。
如果你能在谷歌地图上提供一张你试图与之互动的元素的截图,我可以给你更好的例子。
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()
您的代码运行良好,请等待可点击的检查是否可见和已启用。如上所述,不要使用绝对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()