splinter:更快找到元素的方法?

时间:2014-06-10 15:31:18

标签: python splinter

所以我正在使用python splinter library来测试网络应用程序,当我检查某个元素是否存在并且我手动查找每个元素来操作它时,我遇到了一个问题

问题在于,当输入列表大于4个项目或更多时,如果元素不存在则会遇到这种情况,需要12秒以上才能完成。

我也试过设置wait_time = 1,但如果输入列表大于10,如果该元素不存在于页面的任何位置,则总共需要10次。

for i in inputs:
    if browser.element_exists():
        elm = browser.find_element():
        elm.text()

我需要一些方法来加快速度,以便这个元素检查并行发生,而不是一个接一个。我唯一能想到的就是执行我不喜欢的javascript(我希望将它全部保存在python中)。

def get_columns(current_depth,step,element):
    columns = []
    for xpath in xpaths:
        what = parse_xpath(row[2])
        if browser.is_element_present_by_xpath(xpath,wait_time=1):
            element = browser.find_by_xpath(xpath)
            columns.append(element.text)
        else:
            columns.append('none')
    return columns

1 个答案:

答案 0 :(得分:2)

is_element_present_by_xpath代码

def is_element_present_by_xpath(self, xpath, wait_time=None):
    return self.is_element_present(self.find_by_xpath, xpath, wait_time)

使用

def is_element_present(self, finder, selector, wait_time=None):
     wait_time = wait_time or self.wait_time
     end_time = time.time() + wait_time
     while time.time() < end_time:
         if finder(selector):
             return True
     return False

def find_by_xpath(self, xpath, original_find=None, original_query=None):
    original_find = original_find or "xpath"
    original_query = original_query or xpath
    return self.find_by(self.driver.find_elements_by_xpath, 
                        xpath, 
                        original_find=original_find, 
                        original_query=original_query)

您的代码似乎基本上使用了两次相同的功能。一旦你第一次使用find_by_xpath浏览列表以测试元素是否在那里,那么你第二次用它来查找元素。

find_by_xpath会返回ElementList

ElementList有一个方法is_empty()如果它是空的则返回True,也就是说没有匹配。

那么(我还没有测试,但从头顶回答)。

def get_columns(current_depth,step,element):
    columns = []
    for xpath in xpaths:
        what = parse_xpath(row[2])
        element_list = browser.find_by_xpath(xpath)
        # You might want to check that your element_list has only 1 element.
        if element_list.is_empty():
            columns.append('none')
        else:
            columns.append(element_list[0].text)
    return columns

它会避免两次通过列表。

更新2014-06-20:

走下兔子洞。 Splinter正在调用selenium wedriver ... self.find_by(self.driver.find_elements_by_xpath, …这是另一个开始阶段。我不确定为什么他们决定这样做而不是直接打电话给selenium。

仅出于测试目的,您应首先尝试使用代码的这一特定部分直接使用selenium,看看您是否注意到性能的巨大差异。如果性能问题来自分裂或来自硒,那将会产生歧视。

在selenium / webdriver / remote / webdriver.py

```def find_elements_by_xpath(self,xpath):     “””     通过xpath查找多个元素。

:Args:
 - xpath - The xpath locator of the elements to be found.

:Usage:
    driver.find_elements_by_xpath("//div[contains(@class, 'foo')]")
"""
return self.find_elements(by=By.XPATH, value=xpath)

```

正在使用:

```def find_elements(self,by = By.ID,value = None):         “””         find_elements_by_ *方法使用的“私有”方法。

    :Usage:
        Use the corresponding find_elements_by_* instead of this.

    :rtype: list of WebElement
    """
    if not By.is_valid(by) or not isinstance(value, str):
        raise InvalidSelectorException("Invalid locator values passed in")

    return self.execute(Command.FIND_ELEMENTS,
                         {'using': by, 'value': value})['value']

```

最后一个是通过JsonWireProtocol直接调用API。在这里,性能高度依赖于Selenium在您的系统和/或浏览器上的实现(如果您使用的话)。

更新2 2014-06-20:

另请注意,特别是对于XPath,它实际上取决于所使用的驱动程序。 Selenium documentation about this specific search

  

在较高的层面上,WebDriver尽可能使用浏览器的本机XPath功能。在那些没有本机XPath支持的浏览器上,我们提供了自己的实现。除非您了解各种xpath引擎中的差异,否则这可能会导致一些意外行为。