Python 硒,是否存在多种元素中的一种?
在回答问题的基础上,我试图创建一种方法,允许使用预期条件轮询多个元素 我收到一个错误“bool”对象不可在包含以下内容的行上调用:wait.untilanyexpections 其思想过程是允许将大量XPath作为预期条件传递,然后使用与此基于java的答案类似的方式,检查是否存在任何条件 在这种情况下,正确的使用方法是什么?或者更好的是,需要做些什么才能让这种方法发挥作用 假设Selenium.get'url'在调用此方法之前已经执行Python 硒,是否存在多种元素中的一种?,python,selenium,web-scraping,expected-condition,Python,Selenium,Web Scraping,Expected Condition,在回答问题的基础上,我试图创建一种方法,允许使用预期条件轮询多个元素 我收到一个错误“bool”对象不可在包含以下内容的行上调用:wait.untilanyexpections 其思想过程是允许将大量XPath作为预期条件传递,然后使用与此基于java的答案类似的方式,检查是否存在任何条件 在这种情况下,正确的使用方法是什么?或者更好的是,需要做些什么才能让这种方法发挥作用 假设Selenium.get'url'在调用此方法之前已经执行 def wait_with_xpath_expectati
def wait_with_xpath_expectation(self, search_elements, timeout=6, max_attempts=3):
"""
Selenium wait for an element(s) designated by Xpath to become available in the DOM. Useful for javascript AJAXy
loading pages where content may be be rendered dynamically on the client side after page load appears complete.
search_elements may be one Xpath as a string or many as a list. This allows for any of multiple elements on a
page or pages to be determined to have loaded based on expectations.
:param search_elements: string or list (strings converted to lists), Xpath(s)
:param timeout: int, seconds
:param max_attempts: int, time to wait before giving up on page loading
:return: Boolean, True if page has loaded, False if all attempts have failed
"""
# Page is not loaded yet
loaded = False
# Initialize attempt count
attempt = 0
# If only one element has been passed, ensure it is encapsulated by a list
if type(search_elements) is str:
search_elements = [search_elements]
# Begin the polling loop
while attempt < max_attempts:
try:
while loaded is False:
# Create a list of expected elements using list comprehension
expectations = [EC.presence_of_element_located((By.XPATH, element)) for element in search_elements]
# Define wait
wait = WebDriverWait(self.browser, timeout)
# Execute
wait.until(any(expectations))
# Acknowledge load
loaded = True
print("Success: Page loaded based on expectations")
# Exit returning True for load
return loaded
except TimeoutException as e:
# Increment attempts
attempt += 1
# Check again if max attempts has not been exceeded
while attempt < max_attempts:
# Increase timeout by 20%
timeout *= .2
# Try again
continue
# Print an error if max attempts is exceeded
print("Error: Max load with expectations attempts exceeded,", e)
# Exit returning False for load
return loaded
一旦我意识到Xpath具有联合功能,下面的方法就可以工作了。我会留下这个答案,以防其他人有更好的答案
def wait_with_xpath_expectation(self, search_elements, timeout=6, max_attempts=3):
"""
Selenium wait for an element designated by Xpath to become available in the DOM. Useful for javascript AJAXy
loading pages where content may be be rendered dynamically on the client side after page load appears complete.
search_elements may be one Xpath as a string or many as a list. This allows for any of multiple elements on a
page or pages to be determined to have loaded based on expectations.
:param search_elements: string or list (strings converted to lists), Xpath(s)
:param timeout: int, seconds
:param max_attempts: int, time to wait before giving up on page loading
:return: Boolean, True if page has loaded, False if all attempts have failed
"""
# Page is not loaded yet
loaded = False
# Initialize attempt count
attempt = 0
# If only one element has been passed, ensure it is encapsulated by a list
if type(search_elements) is str:
search_elements = [search_elements]
# Begin the polling loop
while attempt < max_attempts:
try:
while loaded is False:
# Decompose the list of Xpaths to a union of nodes
node_union = " | ".join(search_elements)
expectation = EC.presence_of_element_located((By.XPATH, node_union))
# Define wait
wait = WebDriverWait(self.browser, timeout)
# Execute
wait.until(expectation)
# Acknowledge load
loaded = True
print("Success: Page loaded based on expectations")
# Exit returning True for load
return loaded
except TimeoutException as e:
# Increment attempts
attempt += 1
# Check again if max attempts has not been exceeded
while attempt < max_attempts:
# Increase timeout by 20%
timeout *= .2
# Try again
continue
# Print an error if max attempts is exceeded
print("Error: Max load with expectations attempts exceeded,", e)
# Exit returning False for load
return loaded
一旦我意识到Xpath具有联合功能,下面的方法就可以工作了。我会留下这个答案,以防其他人有更好的答案
def wait_with_xpath_expectation(self, search_elements, timeout=6, max_attempts=3):
"""
Selenium wait for an element designated by Xpath to become available in the DOM. Useful for javascript AJAXy
loading pages where content may be be rendered dynamically on the client side after page load appears complete.
search_elements may be one Xpath as a string or many as a list. This allows for any of multiple elements on a
page or pages to be determined to have loaded based on expectations.
:param search_elements: string or list (strings converted to lists), Xpath(s)
:param timeout: int, seconds
:param max_attempts: int, time to wait before giving up on page loading
:return: Boolean, True if page has loaded, False if all attempts have failed
"""
# Page is not loaded yet
loaded = False
# Initialize attempt count
attempt = 0
# If only one element has been passed, ensure it is encapsulated by a list
if type(search_elements) is str:
search_elements = [search_elements]
# Begin the polling loop
while attempt < max_attempts:
try:
while loaded is False:
# Decompose the list of Xpaths to a union of nodes
node_union = " | ".join(search_elements)
expectation = EC.presence_of_element_located((By.XPATH, node_union))
# Define wait
wait = WebDriverWait(self.browser, timeout)
# Execute
wait.until(expectation)
# Acknowledge load
loaded = True
print("Success: Page loaded based on expectations")
# Exit returning True for load
return loaded
except TimeoutException as e:
# Increment attempts
attempt += 1
# Check again if max attempts has not been exceeded
while attempt < max_attempts:
# Increase timeout by 20%
timeout *= .2
# Try again
continue
# Print an error if max attempts is exceeded
print("Error: Max load with expectations attempts exceeded,", e)
# Exit returning False for load
return loaded
您可以使用预期条件类等待预期条件的组合。这里有一个例子
class wait_for_all(object):
def __init__(self, methods):
self.methods = methods
def __call__(self, driver):
try:
for method in self.methods:
if not method(driver):
return False
return True
except StaleElementReferenceException:
return False
然后,通过构建一个预期条件数组并在同一等待中检查所有这些条件,就可以使用这种方法。为清晰起见,示例行被拆分
methods = []
methods.append(EC.visibility_of_element_located(BY.ID, "idElem1"))
methods.append(EC.visibility_of_element_located(BY.ID, "idElem2"))
method = wait_for_all(methods)
WebDriverWait(driver, 5).until(method)
这将在检查两个不同元素的可见性时执行一次五秒钟的等待
我在一篇博客文章中进一步记录了这一点。您可以使用一个预期条件类来等待预期条件的组合。这里有一个例子
class wait_for_all(object):
def __init__(self, methods):
self.methods = methods
def __call__(self, driver):
try:
for method in self.methods:
if not method(driver):
return False
return True
except StaleElementReferenceException:
return False
然后,通过构建一个预期条件数组并在同一等待中检查所有这些条件,就可以使用这种方法。为清晰起见,示例行被拆分
methods = []
methods.append(EC.visibility_of_element_located(BY.ID, "idElem1"))
methods.append(EC.visibility_of_element_located(BY.ID, "idElem2"))
method = wait_for_all(methods)
WebDriverWait(driver, 5).until(method)
这将在检查两个不同元素的可见性时执行一次五秒钟的等待
我在一篇博客文章中对此做了进一步的记录。进一步的研究发现,我可以执行节点的联合,并将Xpath地址与|组合成一个Xpath。仍在研究解决方案。进一步的研究发现,我可以执行节点的联合,并将Xpath地址与|组合成一个Xpath。还在研究解决方案。嗨,蒂姆。我比我更喜欢这个实现,谢谢!可以显式地等待多个DOM元素,而不是联合。除此之外,它看起来很容易使用。我要更改的一项是BY.ID到BY.XPATH,因为我发现有些站点没有正确使用class和ID标记,但是由于DOM的原因,XPATH总是存在。接受回答,谢谢。我刚刚使用By.ID作为示例元素定位器类型。由于每个预期条件都是单独创建的,因此可以根据该图元的情况组合不同的定位器类型。一个元素可以按.ID定位,另一个元素可以使用By.XPATH、By.NAME、By.CLASS\u NAME、By.TAG\u NAME、By.CSS\u选择器等。接受答案这是完美的答案,但现在selenium所定位的元素的预期条件函数可见性将参数作为1元组。Hi Tim。我比我更喜欢这个实现,谢谢!可以显式地等待多个DOM元素,而不是联合。除此之外,它看起来很容易使用。我要更改的一项是BY.ID到BY.XPATH,因为我发现有些站点没有正确使用class和ID标记,但是由于DOM的原因,XPATH总是存在。接受回答,谢谢。我刚刚使用By.ID作为示例元素定位器类型。由于每个预期条件都是单独创建的,因此可以根据该图元的情况组合不同的定位器类型。一个元素可以按.ID定位,另一个可以使用By.XPATH、By.NAME、By.CLASS\u NAME、By.TAG\u NAME、By.CSS\u选择器等。接受答案这是完美的答案,但现在selenium所定位的元素的预期条件函数可见性将参数作为1元组。