Skip to main content
 首页 » 编程设计

python之用于 Python 的 Selenium Webdriver 循环问题

2025年05月04日31lvdongjie

我在使用 WebDriver for Python 时遇到了一个非常奇怪的问题。基本上,我有一个 Action block ,当它们单独运行时,它们可以完美地工作:

driver.find_element_by_id("lbAdd").click() 
driver.find_element_by_id("lblAutoAssignAdvId").click() 
driver.find_element_by_id("txtCampaignName").clear() 
driver.find_element_by_id("txtCampaignName").send_keys("Campaign X") 
Select(driver.find_element_by_id("ddlCampaignTypes")).select_by_visible_text("Type 1") 
driver.find_element_by_id("btnCampaignSave").click() 

但是当我尝试做不止一个时,即将它放入一个循环中:

x=1 
while (x < 3): 
    driver.find_element_by_id("lbAdd").click() 
    driver.find_element_by_id("lblAutoAssignAdvId").click() 
    driver.find_element_by_id("txtCampaignName").clear() 
    driver.find_element_by_id("txtCampaignName").send_keys("Campaign X") 
    Select(driver.find_element_by_id("ddlCampaignTypes")).select_by_visible_text("Type 1") 
    driver.find_element_by_id("btnCampaignSave").click() 
    x=x+1 

我一直收到这个错误:

Unable to locate element: {"method":"id","selector":"lblAutoAssignAdvId"} 

看起来循环试图只循环第一个 Action

driver.find_element_by_id("lbAdd").click() 

没有继续他们的其余部分。还有其他人经历过吗?谢谢

编辑:

这里是整个事情的大部分。该域受登录保护,因此我无法包含 base_url。除此之外,其他一切都在这里。我还要添加另一个观察结果:我之前尝试包含循环,以包含我在下面粘贴的所有内容,包括打开浏览器的操作。发生的事情是该程序多次在空白页面上打开浏览器。这就是让我得出这样一个理论的原因,即循环只是循环第一个 Action ,而不是整个 Action block 。我认为 ti 可能是一个简单的语法错误(我想循环的 block 周围有 {} 之类的东西,但是唉,也没有运气)

#Open Firefox 
driver = webdriver.Firefox() 
 
#Login in to Database    
driver.get(base_url + "/Login.aspx?return=Default.aspx") 
driver.find_element_by_id("txtUsername").clear() 
driver.find_element_by_id("txtUsername").send_keys(username) 
driver.find_element_by_id("txtPassword").clear() 
driver.find_element_by_id("txtPassword").send_keys(password) 
driver.find_element_by_id("btnLogin").click() 
 
#Waaaaaaait for it 
time.sleep(10) 
 
#Select Campaign Table 
Select(driver.find_element_by_id("ddlTables")).select_by_visible_text("Campaign") 
driver.find_element_by_css_selector("option[value=\"Campaign\"]").click() 
 
#Fill in Camapign Info Fields & Save 
driver.find_element_by_id("lbAdd").click() 
driver.find_element_by_id("lblAutoAssignAdvId").click() 
driver.find_element_by_id("txtCampaignName").clear() 
driver.find_element_by_id("txtCampaignName").send_keys("Campaign X") 
Select(driver.find_element_by_id("ddlCampaignTypes")).select_by_visible_text("Type 1") 
driver.find_element_by_id("btnCampaignSave").click() 

编辑 2:

感谢 German 提供的解决方案。我猜 webdriver 在继续下一步之前需要一些周期性的中断来加载东西,因此循环失败。此代码有效:

for x in range(0,1000):  
    driver.find_element_by_id("lbAdd").click() 
    time.sleep(1) 
    driver.find_element_by_id("lblAutoAssignAdvId").click() 
    time.sleep(1) 
    driver.find_element_by_id("txtCampaignName").clear() 
    driver.find_element_by_id("txtCampaignName").send_keys("Campaign X") 
    Select(driver.find_element_by_id("ddlCampaignTypes")).select_by_visible_text("Type 1") 
    driver.find_element_by_id("btnCampaignSave").click() 
    time.sleep(2) 

请您参考如下方法:

这是 German's 的替代方法答案(来自上面的评论)将大大减少等待时间:

定义这个等待元素并在元素可用时立即返回的方法:

from selenium.webdriver.common.by import By 
from selenium.webdriver.support.ui import WebDriverWait 
from selenium.webdriver.support import expected_conditions as EC 
from selenium.common.exceptions import TimeoutException 
 
 
def wait_for_element_by_id(self, element_id, timeout): 
    try: 
        return WebDriverWait(driver, timeout).until(EC.presence_of_element_located((By.ID, element_id))) 
    except TimeoutException: 
        return None 
        # or do something else here 

然后替换

time.sleep(1) 
driver.find_element_by_id("lblAutoAssignAdvId").click() 

与

wait_for_element_by_id("lblAutoAssignAdvId", 1).click() 

或者只是

WebDriverWait(driver, 1).until(EC.presence_of_element_located((By.ID, "lblAutoAssignAdvId"))) 

如果您不关心定义函数。

我发现等待条件而不是等待明确的时间通常是一种很好的做法,这样做将使您的自动化必须更快。您可能会遇到这样的情况,尽管您正在等待的 DOM 元素存在,但它可能尚未显示,并且尝试对其调用 click() 将引发 ElementNotVisibleException。在这种情况下,您可能希望在点击之前使用 expected_conditions.visibility_of()。