使用Python+Selenium操作Chrome时,Google Maps无法添加多目的地
Google Maps自动化添加地点覆盖问题修复
问题描述
我尝试用Selenium自动化在Google Maps中添加多个地点,当前遇到的问题:添加第一个地点、获取路线后添加第二个地点均正常,但添加第三个地点时会覆盖已添加的第二个地点。推测问题出在重复的div元素定位上。
运行效果说明:
- 运行
add_point后:已成功添加起点和第一个途经点,路线显示正常 - 运行
add_point2后:第一个途经点被第三个地点覆盖,仅显示起点和终点
原始代码
from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.common.by import By from selenium import webdriver #automation proceess library from selenium.webdriver.support.ui import WebDriverWait # 原始代码漏导入该类 from time import sleep driver = webdriver.Chrome(r"C:\\Users\\Patrick\\Desktop\\Practica\\chromedriver.exe") wait = WebDriverWait(driver, 5) driver.get("https://www.google.com/maps/@31.4855012,74.3470166,15z") sleep(2) try: frame = driver.find_element("xpath", '//*[@id="cnsw"]/iframe') driver.switch_to.frame(frame) driver.find_element("xpath", '//*[@id="yDmH0d"]').click() except NoSuchElementException: driver.find_element("xpath", '//*[@id="yDmH0d"]/c-wiz/div/div/div/div[2]/div[1]/div[3]/div[1]/div[1]/form[2]/div/div/button/span').click() def searchplace(): element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "searchboxinput"))) element.click() element.send_keys("Hotel Continental, Bulevardul Revoluției din 1989 2A, Timișoara") submit= driver.find_element("xpath", "/html/body/div[3]/div[9]/div[3]/div[1]/div[1]/div[1]/div[2]/div[1]/button") submit.click() sleep(3) searchplace() def directions(): sleep(10) element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CLASS_NAME, "EgL07d"))) element.click() sleep(5) directions() def add_point(): sleep(5) point1= driver.find_element("xpath", "/html/body/div[3]/div[9]/div[3]/div[1]/div[2]/div/div[3]/button/div[1]/div") point1.click() submit= driver.find_element("xpath", "/html/body/div[3]/div[9]/div[3]/div[1]/div[2]/div/div[3]/div[1]/div[3]/div[2]/div[1]/div/input") submit.send_keys("Căminul 22C, Aleea Studenților 6, Timișoara") submit= driver.find_element("xpath", "/html/body/div[3]/div[9]/div[3]/div[1]/div[2]/div/div[3]/div[1]/div[3]/div[2]/button[1]") submit.click() sleep(4) add_point() def add_point2(): point2= driver.find_element("xpath", "/html/body/div[3]/div[9]/div[3]/div[1]/div[2]/div/div[3]/button/div[1]/div") point2.click() submit= driver.find_element("xpath", "/html/body/div[3]/div[9]/div[3]/div[1]/div[2]/div/div[3]/div[1]/div[3]/div[2]/div[1]/div/input") submit.send_keys("Hotel Boavista, Aleea F. C. Ripensia 7/A, Timișoara 300575") submit= driver.find_element("xpath", "/html/body/div[3]/div[9]/div[3]/div[1]/div[2]/div/div[3]/div[1]/div[3]/div[2]/button[1]") submit.click() sleep(20) add_point2()
问题根源
你使用了绝对XPath定位添加按钮和输入框,而Google Maps在添加途经点后,页面DOM结构会动态变化:原本的输入框位置会变成已添加的地点,新增的输入框会出现在下方。但绝对XPath始终指向同一个固定位置,导致第二次点击时,实际编辑的是第二个地点的输入框,而非新增的途经点输入框,最终造成覆盖。
修复方案
使用相对定位+动态选择最新元素的方式,替换绝对XPath,同时合并重复函数提升代码复用性:
修复后代码
from selenium.webdriver.support import expected_conditions as EC from selenium.common.exceptions import NoSuchElementException from selenium.webdriver.common.by import By from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from time import sleep driver = webdriver.Chrome(r"C:\\Users\\Patrick\\Desktop\\Practica\\chromedriver.exe") wait = WebDriverWait(driver, 10) driver.get("https://www.google.com/maps/@31.4855012,74.3470166,15z") sleep(2) # 处理弹窗 try: frame = wait.until(EC.presence_of_element_located((By.XPATH, '//*[@id="cnsw"]/iframe'))) driver.switch_to.frame(frame) wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="yDmH0d"]'))).click() driver.switch_to.default_content() # 切回主文档避免后续定位失败 except NoSuchElementException: wait.until(EC.element_to_be_clickable((By.XPATH, '//*[@id="yDmH0d"]/c-wiz/div/div/div/div[2]/div[1]/div[3]/div[1]/div[1]/form[2]/div/div/button/span'))).click() def search_place(place_name): search_box = wait.until(EC.element_to_be_clickable((By.ID, "searchboxinput"))) search_box.click() search_box.clear() search_box.send_keys(place_name) submit_btn = wait.until(EC.element_to_be_clickable((By.XPATH, '//button[@aria-label="搜索"]'))) submit_btn.click() sleep(3) def open_directions(): directions_btn = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "EgL07d"))) directions_btn.click() sleep(5) def add_intermediate_point(place_name): # 点击"添加途经点"按钮 add_btn = wait.until(EC.element_to_be_clickable((By.XPATH, '//button[@aria-label="添加途经点"]'))) add_btn.click() # 定位最新的输入框(页面最后一个目的地输入框) input_box = wait.until(EC.element_to_be_clickable((By.XPATH, '(//input[@placeholder="输入目的地"])[last()]'))) input_box.send_keys(place_name) # 点击对应输入框的搜索确认按钮 confirm_btn = wait.until(EC.element_to_be_clickable((By.XPATH, '(//button[@aria-label="搜索"])[last()]'))) confirm_btn.click() sleep(4) # 执行流程 search_place("Hotel Continental, Bulevardul Revoluției din 1989 2A, Timișoara") open_directions() add_intermediate_point("Căminul 22C, Aleea Studenților 6, Timișoara") add_intermediate_point("Hotel Boavista, Aleea F. C. Ripensia 7/A, Timișoara 300575") sleep(20) driver.quit()
关键修改点
- 替换绝对XPath:用
@aria-label属性定位按钮,用(//input[@placeholder="输入目的地"])[last()]定位最新的输入框,确保每次操作的是新增的途经点 - 合并重复函数:将
add_point和add_point2合并为add_intermediate_point,通过参数传递地点名称,减少代码冗余 - 优化弹窗处理:添加
driver.switch_to.default_content()切回主文档,避免后续元素定位失败 - 提升稳定性:尽量用
WebDriverWait替代固定sleep,等待元素加载完成后再操作
内容的提问来源于stack exchange,提问作者Patrick Kossik
相关产品推荐
相关产品推荐

