Selenium Python如何在循环中处理多个def的XPath错误?

0 投票
1 回答
22 浏览
提问于 2025-04-12 22:48

我想知道能不能通过像schedule.every(10).seconds.do(example)这样的方式来安排我的代码运行?我想安排我代码中的错误处理部分(XPath),这个部分是在一个While循环里运行的。不过因为在While循环里,它不允许其他的函数运行。我希望XPath/错误处理部分能和我的Selenium窗口一起循环运行,但又能检测到其他函数的运行而不干扰它们。它应该只是检测XPath是否存在,如果不存在就运行一个异常处理。有没有人能给我个解决办法?

我的代码:

def example():
    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)

    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")
            pyautogui.moveTo(89, 56)
            time.sleep(1)
            pyautogui.click()

        time.sleep(10)


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

    driver = webdriver.Firefox(service=FirefoxService(GeckoDriverManager().install()))

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

    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")
            pyautogui.moveTo(850, 57)
            time.sleep(1)
            pyautogui.click()

schedule.every().day.at("22:59").do(example)
schedule.every().day.at("22:59").do(example2)

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


1 个回答

1

你现在的做法是在你的 exampleexample2 函数里使用了一个阻塞的 while True 循环,这个循环会不停地检查某个元素是否存在,方法是通过它的 XPath。这种做法会阻止其他代码的执行,包括一些定时任务,因为 Python 默认是单线程的。如果代码的一部分在无限循环中或者在执行一个很长的操作,其他的代码就会被“冻结”,无法运行。

我的建议是,你可以使用 Python 的 threading 库,把你的阻塞循环放在单独的线程里。这样一来,你的主程序就可以继续运行,执行其他定时任务,而不会被 exampleexample2 中的无限循环给阻塞住。

import threading
import schedule
import time
# Import other necessary modules like Selenium, pyautogui, etc.

def example():
    # Your existing code for example function

def example2():
    # Your existing code for example2 function

# Schedule tasks as before
schedule.every().day.at("22:59").do(example)
schedule.every().day.at("22:59").do(example2)

# Run the example functions in their threads
example_thread = threading.Thread(target=example)
example2_thread = threading.Thread(target=example2)

example_thread.start()
example2_thread.start()

# Run the scheduler in the main thread
while True:
    schedule.run_pending()
    time.sleep(1)

还有另一种方法可以尝试。与其在 exampleexample2 函数里使用 while True 循环,不如考虑重新组织你的代码,让它在固定的时间间隔内检查元素。这可以直接用 schedule 库来实现,定时安排检查,而不是放在无限循环里。

比如,你可以创建一个专门用来检查元素是否存在的函数,然后把这个函数安排每10秒左右运行一次,和其他任务一起进行。这样就避免了阻塞循环的需要,让调度器来管理检查的时间。

对于处理一些异常情况,比如找不到元素(这似乎是你最关心的问题),确保把相关的代码部分放在一个 try-except 块里。这样可以捕捉到与元素不存在相关的异常,让你的代码能够做出相应的反应(比如,点击页面上的其他地方)。

请注意,多个线程同时访问共享资源可能会导致竞争条件。如果有必要,使用线程锁来避免这些问题。

希望这些对你有帮助。谢谢!

撰写回答