我对WebDriver for Python有一个非常奇怪的问题。基本上,我有一系列的行动,当它们独立运行时,可以完美地运作:
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"}
似乎循环试图循环第一个动作
driver.find_element_by_id("lbAdd").click()
没有继续其余的。还有其他人经历过这个吗?感谢
这是整个事情的大部分内容。该域受登录保护,因此我无法包含base_url。除此之外,其他一切都在这里。我还将添加另一个观察:我尝试先包含循环,以包含我在下面粘贴的所有内容,包括打开浏览器的操作。发生的事情是该程序刚刚在空白页面上打开浏览器很多次。这就是导致我认为循环只是循环第一个动作的理论,而不是它们的整个块。我认为ti可能是一个简单的语法错误(在我想要循环的块周围有类似{}的东西,但是唉,也没有运气)
#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()
感谢德国人的解决方案。我猜想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)
答案 0 :(得分:0)
以下是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()
。