硒等待元素

发布于 2024-12-10 07:10:56 字数 90 浏览 0 评论 0原文

如何在 Python 中为 Selenium 编写等待只有类标识符的表的函数?我正在花很长时间学习使用 Selenium 的 Python webdriver 函数。

How do I write the function for Selenium to wait for a table with just a class identifier in Python? I'm having a devil of a time learning to use Selenium's Python webdriver functions.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

你的他你的她 2024-12-17 07:10:56

来自 Selenium 文档 PDF

import contextlib
import selenium.webdriver as webdriver
import selenium.webdriver.support.ui as ui

with contextlib.closing(webdriver.Firefox()) as driver:
    driver.get('http://www.google.com')
    wait = ui.WebDriverWait(driver,10)
    # Do not call `implicitly_wait` if using `WebDriverWait`.
    #     It magnifies the timeout.
    # driver.implicitly_wait(10)  
    inputElement=driver.find_element_by_name('q')
    inputElement.send_keys('Cheese!')
    inputElement.submit()
    print(driver.title)

    wait.until(lambda driver: driver.title.lower().startswith('cheese!'))
    print(driver.title)

    # This raises
    #     selenium.common.exceptions.TimeoutException: Message: None
    #     after 10 seconds
    wait.until(lambda driver: driver.find_element_by_id('someId'))
    print(driver.title)

From the Selenium Documentation PDF :

import contextlib
import selenium.webdriver as webdriver
import selenium.webdriver.support.ui as ui

with contextlib.closing(webdriver.Firefox()) as driver:
    driver.get('http://www.google.com')
    wait = ui.WebDriverWait(driver,10)
    # Do not call `implicitly_wait` if using `WebDriverWait`.
    #     It magnifies the timeout.
    # driver.implicitly_wait(10)  
    inputElement=driver.find_element_by_name('q')
    inputElement.send_keys('Cheese!')
    inputElement.submit()
    print(driver.title)

    wait.until(lambda driver: driver.title.lower().startswith('cheese!'))
    print(driver.title)

    # This raises
    #     selenium.common.exceptions.TimeoutException: Message: None
    #     after 10 seconds
    wait.until(lambda driver: driver.find_element_by_id('someId'))
    print(driver.title)
逆蝶 2024-12-17 07:10:56

Selenium 2 的 Python 绑定有一个名为 Expected_conditions.py 的新支持类,用于执行各种操作,例如测试元素是否可见。 可在此处获取。

注意: 截至 2012 年 10 月 12 日,上述文件已在主干中,但尚未在最新的下载版本中(仍为 2.25)。目前,在新的 Selenium 版本发布之前,您可以暂时将此文件保存在本地并将其包含在导入中,就像我在下面所做的那样。

为了让生活变得更简单,您可以将其中一些预期条件方法与 Selenium wait Until 逻辑结合起来,以创建一些非常方便的功能,类似于 Selenium 1 中提供的功能。例如,我将这个进入我的名为 SeleniumTest 的基类,我的所有 Selenium 测试类都扩展了它:

from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
import selenium.webdriver.support.expected_conditions as EC
import selenium.webdriver.support.ui as ui

@classmethod
def setUpClass(cls):
    cls.selenium = WebDriver()
    super(SeleniumTest, cls).setUpClass()

@classmethod
def tearDownClass(cls):
    cls.selenium.quit()
    super(SeleniumTest, cls).tearDownClass()

# return True if element is visible within 2 seconds, otherwise False
def is_visible(self, locator, timeout=2):
    try:
        ui.WebDriverWait(driver, timeout).until(EC.visibility_of_element_located((By.CSS_SELECTOR, locator)))
        return True
    except TimeoutException:
        return False

# return True if element is not visible within 2 seconds, otherwise False
def is_not_visible(self, locator, timeout=2):
    try:
        ui.WebDriverWait(driver, timeout).until_not(EC.visibility_of_element_located((By.CSS_SELECTOR, locator)))
        return True
    except TimeoutException:
        return False

然后您可以在测试中轻松使用它们,如下所示:

def test_search_no_city_entered_then_city_selected(self):
    sel = self.selenium
    sel.get('%s%s' % (self.live_server_url, '/'))
    self.is_not_visible('#search-error')

Selenium 2's Python bindings have a new support class called expected_conditions.py for doing all sorts of things like testing if an element is visible. It's available here.

NOTE: the above file is in the trunk as of Oct 12, 2012, but not yet in the latest download which is still 2.25. For the time being until a new Selenium version is released, you can just save this file locally for now and include it in your imports like I've done below.

To make life a little simpler, you can combine some of these expected condition methods with the Selenium wait until logic to make some very handy functions similar to what was available in Selenium 1. For example, I put this into my base class called SeleniumTest which all of my Selenium test classes extend:

from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
import selenium.webdriver.support.expected_conditions as EC
import selenium.webdriver.support.ui as ui

@classmethod
def setUpClass(cls):
    cls.selenium = WebDriver()
    super(SeleniumTest, cls).setUpClass()

@classmethod
def tearDownClass(cls):
    cls.selenium.quit()
    super(SeleniumTest, cls).tearDownClass()

# return True if element is visible within 2 seconds, otherwise False
def is_visible(self, locator, timeout=2):
    try:
        ui.WebDriverWait(driver, timeout).until(EC.visibility_of_element_located((By.CSS_SELECTOR, locator)))
        return True
    except TimeoutException:
        return False

# return True if element is not visible within 2 seconds, otherwise False
def is_not_visible(self, locator, timeout=2):
    try:
        ui.WebDriverWait(driver, timeout).until_not(EC.visibility_of_element_located((By.CSS_SELECTOR, locator)))
        return True
    except TimeoutException:
        return False

You can then use these easily in your tests like so:

def test_search_no_city_entered_then_city_selected(self):
    sel = self.selenium
    sel.get('%s%s' % (self.live_server_url, '/'))
    self.is_not_visible('#search-error')
自演自醉 2024-12-17 07:10:56

我使用以下方法获得了良好的体验:

  • time.sleep(seconds)
  • webdriver.Firefox.implicitly_wait(seconds)

第一个非常明显 - 只需等待几秒钟即可完成某些操作。

对于我的所有 Selenium 脚本,当我在笔记本电脑上运行它们时,几秒钟(范围从 1 到 3 秒)的 sleep() 就可以工作,但在我的服务器上等待的时间范围更广,所以我也使用implicitly_wait()。我通常使用implicitly_wait(30),这确实足够了。

隐式等待是告诉 WebDriver 在尝试查找一个或多个元素(如果它们不能立即可用)时轮询 DOM 一段时间。默认设置为 0。设置后,将在 WebDriver 对象实例的生命周期内设置隐式等待。

I have made good experiences using:

  • time.sleep(seconds)
  • webdriver.Firefox.implicitly_wait(seconds)

The first one is pretty obvious - just wait a few seconds for some stuff.

For all my Selenium Scripts the sleep() with a few seconds (range from 1 to 3) works when I run them on my laptop, but on my Server the time to wait has a wider range, so I use implicitly_wait() too. I usually use implicitly_wait(30), which is really enough.

An implicit wait is to tell WebDriver to poll the DOM for a certain amount of time when trying to find an element or elements if they are not immediately available. The default setting is 0. Once set, the implicit wait is set for the life of the WebDriver object instance.

不即不离 2024-12-17 07:10:56

我为 python 的 wait_for_condition 实现了以下内容,因为 python selenium 驱动程序不支持此函数。

def wait_for_condition(c):
for x in range(1,10):
    print "Waiting for ajax: " + c
    x = browser.execute_script("return " + c)
    if(x):
        return
    time.sleep(1)

用作

等待 ExtJS Ajax 调用未挂起:

wait_for_condition("!Ext.Ajax.isLoading()")

设置 Javascript 变量

wait_for_condition("CG.discovery != undefined;")

等。

I implemented the following for python for wait_for_condition since the python selenium driver does not support this function.

def wait_for_condition(c):
for x in range(1,10):
    print "Waiting for ajax: " + c
    x = browser.execute_script("return " + c)
    if(x):
        return
    time.sleep(1)

to be used as

Wait that an ExtJS Ajax call is not pending:

wait_for_condition("!Ext.Ajax.isLoading()")

A Javascript variable is set

wait_for_condition("CG.discovery != undefined;")

etc.

谁的年少不轻狂 2024-12-17 07:10:56

您始终可以在循环中使用短暂睡眠并将其传递给您的元素 id:

def wait_for_element(element):
     count = 1
     if(self.is_element_present(element)):
          if(self.is_visible(element)):
              return
          else:
              time.sleep(.1)
              count = count + 1
     else:
         time.sleep(.1)
         count = count + 1
         if(count > 300):
             print("Element %s not found" % element)
             self.stop
             #prevents infinite loop

You could always use a short sleep in a loop and pass it your element id:

def wait_for_element(element):
     count = 1
     if(self.is_element_present(element)):
          if(self.is_visible(element)):
              return
          else:
              time.sleep(.1)
              count = count + 1
     else:
         time.sleep(.1)
         count = count + 1
         if(count > 300):
             print("Element %s not found" % element)
             self.stop
             #prevents infinite loop
原谅过去的我 2024-12-17 07:10:56

Wait Until Page Contains Element 与正确的 XPath 定位器结合使用。例如,给定以下 HTML:

<body>
  <div id="myDiv">
    <table class="myTable">
      <!-- implementation -->
    </table>
  </div>
</body>

... 您可以输入以下关键字:

Wait Until Page Contains Element  //table[@class='myTable']  5 seconds

除非我错过了某些内容,否则无需为此创建新函数。

Use Wait Until Page Contains Element with the proper XPath locator. For example, given the following HTML:

<body>
  <div id="myDiv">
    <table class="myTable">
      <!-- implementation -->
    </table>
  </div>
</body>

... you can enter the following keyword:

Wait Until Page Contains Element  //table[@class='myTable']  5 seconds

Unless I missed something, there is no need to create a new function for this.

木緿 2024-12-17 07:10:56

如果这有帮助...

在 Selenium IDE 中,我添加了...
命令:waitForElementPresent
Target: //table[@class='pln']

然后我做了 File>Export TestCase As Python2(Web Driver),它给了我这个...

def test_sel(self):
    driver = self.driver
    for i in range(60):
        try:
            if self.is_element_present(By.XPATH, "//table[@class='pln']"): break
        except: pass
        time.sleep(1)
    else: self.fail("time out")

In case this helps ...

In the Selenium IDE, I added ...
Command: waitForElementPresent
Target: //table[@class='pln']

Then I did File>Export TestCase As Python2(Web Driver), and it gave me this ...

def test_sel(self):
    driver = self.driver
    for i in range(60):
        try:
            if self.is_element_present(By.XPATH, "//table[@class='pln']"): break
        except: pass
        time.sleep(1)
    else: self.fail("time out")
幽蝶幻影 2024-12-17 07:10:56

更简单的解决方案:

    from selenium.webdriver.common.by import By    
    import time

    while len(driver.find_elements(By.ID, 'cs-paginate-next'))==0:
        time.sleep(100)

easier solution:

    from selenium.webdriver.common.by import By    
    import time

    while len(driver.find_elements(By.ID, 'cs-paginate-next'))==0:
        time.sleep(100)
半葬歌 2024-12-17 07:10:56

希望这有帮助

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By   


driver = webdriver.Firefox()
driver.get('www.url.com')

try:
    wait = driver.WebDriverWait(driver,10).until(EC.presence_of_element_located(By.CLASS_NAME,'x'))
except:
    pass

Hopefully this helps

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By   


driver = webdriver.Firefox()
driver.get('www.url.com')

try:
    wait = driver.WebDriverWait(driver,10).until(EC.presence_of_element_located(By.CLASS_NAME,'x'))
except:
    pass
面如桃花 2024-12-17 07:10:56

如果我不了解 selenium 命令,我会在 firefox 中使用 selenium web idea RC。您可以在组合框中选择并添加命令,完成测试用例后可以将测试代码导出为不同的语言。比如java、ruby、phyton、C#等。

If I don't know something about selenium command, I use selenium web idea RC with firefox. You can choose and add command in the combobox and when finish your test case after you can export the test code different language. like java, ruby, phyton, C#, etc..

逆夏时光 2024-12-17 07:10:56

您可以将此功能修改为所有类型的元素。下面的仅针对类元素:

其中“driver”是驱动程序,“element_name”是您要查找的类名称,“sec”是您愿意等待的最大秒数。

def wait_for_class_element(driver,element_name,sec):

    for i in range(sec):        
        try:
            driver.find_element_by_class_name(element_name)
            break
        except:        
            print("not yet")
            time.sleep(1)

You can modify this function to all type of elements. The one below is just for the class element:

Where "driver" is the driver, "element_name" is the class name you are looking for, and "sec" is the maximum amount of seconds you are willing to wait.

def wait_for_class_element(driver,element_name,sec):

    for i in range(sec):        
        try:
            driver.find_element_by_class_name(element_name)
            break
        except:        
            print("not yet")
            time.sleep(1)
吾性傲以野 2024-12-17 07:10:56

我找到了一种使用自定义函数更简单的方法来构建它,该函数本质上是递归的。

from selenium import webdriver
import time

def wait_element_by_id(id_value):
    try:
        elem = driver.find_element_by_id(id_value)
    except:
        time.sleep(2)
        print 'Waiting for id '+id_value
        wait_element_by_id(id_value)

您可以根据您的情况将 find_element_by_id 替换为 find_element_by_namefind_element_by_tag_name要求

I found an easier way to build this using a custom function, which is recursive in nature

from selenium import webdriver
import time

def wait_element_by_id(id_value):
    try:
        elem = driver.find_element_by_id(id_value)
    except:
        time.sleep(2)
        print 'Waiting for id '+id_value
        wait_element_by_id(id_value)

You can replace find_element_by_id with find_element_by_name or find_element_by_tag_name based on your requirement

后来的我们 2024-12-17 07:10:56
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


# wait until present
WebDriverWait(driver, waittime).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, css_selector))
)

# wait until visible
WebDriverWait(driver, waittime).until(
    EC.visibility_of_element_located((By.CSS_SELECTOR, css_selector))
)
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


# wait until present
WebDriverWait(driver, waittime).until(
    EC.presence_of_element_located((By.CSS_SELECTOR, css_selector))
)

# wait until visible
WebDriverWait(driver, waittime).until(
    EC.visibility_of_element_located((By.CSS_SELECTOR, css_selector))
)
苏璃陌 2024-12-17 07:10:56

我希望这可能有所帮助:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

driver = webdriver.Chrome()
driver.get(myURL)
wait = WebDriverWait(driver, 10) 

wait.until(ec.presence_of_element_located((By.XPATH, myXPATH)))

我建议您阅读这篇文章让它更清楚。

I hope that's might help:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as ec

driver = webdriver.Chrome()
driver.get(myURL)
wait = WebDriverWait(driver, 10) 

wait.until(ec.presence_of_element_located((By.XPATH, myXPATH)))

I recommend you to read this article to make it more clear.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文