Selenium - 如何查找一个元素 ID,如果不存在,请查找下一个元素 ID?



我有一个小的硒脚本,去一个网站,检查一些东西,并执行一些步骤。我的问题是。"s2id_ddlHotels"ID有时会改变。机器人会找到"s2id_ddlhotels";完成步骤。但是下一次运行时,它将加载这个元素"s2id_ddlhotelswithdate"。到目前为止,我只在这两个元素之间看到过。我该如何处理?告诉python代码查找"s2id_ddlHotels"首先,如果找到了,执行其他步骤。如果找不到,请查找"s2id_ddlhotelswithdate";做这些步骤?我相信我必须在这里使用IF语句,但我不确定如何正确实现它。

我的当前代码:

try:
time.sleep(5)
driver.find_element_by_id("s2id_ddlHotels").click() #issue here
time.sleep(2)
driver.find_element_by_id('s2id_autogen1_search').send_keys(hotelName)
time.sleep(2)
driver.find_element_by_id('s2id_autogen1_search').send_keys(Keys.RETURN)
time.sleep(2)
driver.find_element_by_name("fileRoomIncomeName").send_keys(fileName)
time.sleep(2)
element = driver.find_element_by_class_name("fileupload-preview")
driver.execute_script(f"arguments[0].innerText = '{fileName}'", element)
except Exception as e:
pass
#print(e)

您只需要使用Selenium的预期条件等待系统。这允许您在期望的时间内安全地等待元素。如果你开始像我一样把它包装起来,它会变得更容易管理。

下面是您正在寻找的基本示例。它并不完美,但足以让你开始。

import os
import sys
from typing import Union
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.remote.webelement import WebElement
# We are assuming the webdriver is right next to this file
THIS_FILE = os.path.abspath(__file__)
THIS_DIR = os.path.dirname(THIS_FILE)
# I am on linux so no *.exe file
CHROME_DRIVER_PATH = os.path.join(THIS_DIR, 'chromedriver')

# Get the driver
driver = webdriver.Chrome(executable_path=CHROME_DRIVER_PATH)

def get_element_by_locator(the_driver, locator: str, timeout: int = 10, by=By.ID) -> Union[None, WebElement]:
"""Explicit waits by Selenium: https://selenium-python.readthedocs.io/waits.html#explicit-waits
:param the_driver: The instantiated driver you created
:param locator: the string locator value
:param timeout: Default wait time before giving up
:param by: What is the locator searching By? is it an ID, XPATH, CLASSNAME?
:return: None if not found else the found WebElement
"""
try:
return WebDriverWait(the_driver, timeout).until(
expected_conditions.presence_of_element_located((by, locator))
)
except TimeoutException:
# We could not find the element matching matched the locator
# By returning None we can make an educated decision about what to do next
return None

# Notice I don't have to sleep by 5 seconds anymore.
# Selenium will search for the element for up to 5 seconds before giving up.
# In that case you are going to get None or the desired element.
# Maybe you can set it to 60 seconds and if it finds it with in 6 seconds 
# you can still safely move on. Worst case you waited 60 seconds and then got None.
hotels_button = get_element_by_locator(driver, 's2id_ddlHotels', timeout=5, by=By.ID)
if hotels_button is not None:
print('Happy times the page is in the desired state')
hotels_button.click()
else:
print('I did not find my element, no point in continuing')
print('I can attempt to recover, reload the page or just quit')
sys.exit(1)
# If you notice we only checked if the first element existed.
# Every thing below here in theory could be None also.
hotels_search_input = get_element_by_locator(driver, 's2id_autogen1_search', timeout=2, by=By.ID)
hotels_search_input.send_keys('hotelName')
hotels_search_input.send_keys(Keys.RETURN)
file_name = 'my_file'
file_name_input = get_element_by_locator(driver, 'fileRoomIncomeName', timeout=2, by=By.NAME)
file_name_input.send_keys(file_name)
file_upload_preview = get_element_by_locator(driver, "fileupload-preview", timeout=2, by=By.CLASS_NAME)
driver.execute_script(f"arguments[0].innerText = '{file_name}'", file_upload_preview)

最新更新