所以我使用python splinter库来测试一个web应用程序,当我检查一个元素是否存在并且我手动找到每个元素来操作它时,我遇到的问题如下。
问题是,当输入列表大于或大于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
is_element_present_by_xpath
code is
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,看看您是否注意到性能上的巨大差异。这将区分性能问题是来自splinter还是来自selenium。
在硒/webdriver/远程/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值= 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实现(如果使用的话)。
UPDATE 2 2014-06-20:
还要注意,特别是对于XPath,它实际上取决于所使用的驱动程序。关于此特定搜索的Selenium文档:
在高层,WebDriver尽可能使用浏览器的原生XPath功能。在那些没有原生XPath支持的浏览器上,我们提供了自己的实现。这可能会导致一些意想不到的行为,除非您了解各种xpath引擎之间的差异。