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 年 6 月 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 的实现,如果你正在使用的话。
2014 年 6 月 20 日更新 2:
还请注意,特别是对于 XPath,它实际上取决于所使用的驱动程序。硒documentation about this specific search:
在高层次上,WebDriver 尽可能使用浏览器的原生 XPath 功能。在那些不支持原生 XPath 的浏览器上,我们提供了自己的实现。除非您意识到各种 xpath 引擎的差异,否则这可能会导致一些意外行为。