Selenium Python如何每10秒运行一次XPath错误处理异常?

0 投票
1 回答
49 浏览
提问于 2025-04-12 23:16

我刚开始接触编程,遇到一个项目上的问题。我想让我的代码,特别是处理错误的部分,每隔10到30秒运行一次,检查一下某个XPath(网页元素的路径)是否还存在。如果XPath还在,我希望它什么都不做;如果没找到,我想让它触发一个异常。不过,我现在不知道怎么实现这个,有谁能帮帮我吗?

这是我新的代码。

def code():
    options = Options()
    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()),
                              options=options)

    driver.get("example.com")
    driver.set_window_position(0, 0)
    driver.set_window_size(750, 512)

    try:
        driver.find_element(By.XPATH, "/html/body/div/div/div/div/div[2]/div/div/div[2]/div[2]/div[1]/span/button/span")
        print("success")
    except NoSuchElementException:  # spelling error making this code not work as expected
        pyautogui.moveTo(89, 56)
        time.sleep(1)
        pyautogui.click()
        print("Error but moved to refresh")
        pass


schedule.every().day.at("19:37").do(code)

while True:
    schedule.run_pending()
    time.sleep(1)

我希望这个代码每天运行一次Selenium浏览器窗口,并保持在一个循环中,但我希望处理错误的部分每10秒运行一次,以确保XPath仍然存在。如果没有找到,就触发一个异常。

1 个回答

-1

如果我理解你的情况没错的话,你是想在找不到某个元素时刷新页面。

这里有一些建议:

  1. 与其使用 try-except,不如用 .find_elements() 来查找元素,然后检查一下返回的列表是不是空的。虽然在某些情况下需要用到异常处理,但在这里其实不需要。使用异常会让你的代码变得慢。
  2. 我写的这个代码会一直运行下去,没有时间限制。虽然这样一般来说不是个好主意,但这是你要求的。我建议你去掉这个循环和10秒的等待,直接把这个脚本安排成每分钟运行一次,或者根据需要的频率运行。
  3. 与其用 pyautogui 来点击刷新按钮,不如直接用 Selenium 提供的 driver.refresh。如果我理解你的操作没错的话。
  4. 要让这个操作重复进行,你需要一个循环,使用 while True:,并在每次循环之间加一个暂停,比如 time.sleep(10) 来暂停10秒。
  5. 我知道你是新手,但你现在用的定位方式不是很好。这个定位方式很脆弱,容易出错,因为它是从 /html 开始的,路径很长(有很多层),而且用了索引(比如 /div[2])。如果没有相关的HTML(以文本形式,格式正确)或者页面链接,我无法帮你修正这个问题。

总结一下:
这段代码使用 .find_elements() 来获取你要找的元素集合,检查这个列表是否为空,如果是,就刷新页面。然后它会等待10秒,再无限重复这个过程。

为了让这个过程更干净,我会使用下面的代码。

while True: 
    e = driver.find_elements(By.XPATH, "/html/body/div/div/div/div/div[2]/div/div/div[2]/div[2]/div[1]/span/button/span")
    if not e:
        print("Element not found")
        # driver.refresh or whatever you want to run when the element isn't found

    time.sleep(10) # this is measured in seconds

撰写回答