我有一个列表,它是通过 AJAX 动态加载的。一开始加载时,它的代码是这样的:
<ul><li class="last"><a class="loading" href="#"><ins> </ins>Загрузка...</a></li></ul>
当列表加载时,所有的li和a都会被更改。而且这里始终有多于1个li。
<ul class="ltr">
<li id="t_b_68" class="closed" rel="simple">
<a id="t_a_68" href="javascript:void(0)">Category 1</a>
</li>
<li id="t_b_64" class="closed" rel="simple">
<a id="t_a_64" href="javascript:void(0)">Category 2</a>
</li>
...
我需要检查列表是否已加载,所以我检查它是否具有多个li。
到目前为止,我尝试过:
1)自定义等待条件
class more_than_one(object):
def __init__(self, selector):
self.selector = selector
def __call__(self, driver):
elements = driver.find_elements_by_css_selector(self.selector)
if len(elements) > 1:
return True
return False
...
try:
query = WebDriverWait(driver, 30).until(more_than_one('li'))
except:
print "Bad crap"
else:
# Then load ready list
2)基于find_elements_by的自定义函数
def wait_for_several_elements(driver, selector, min_amount, limit=60):
"""
This function provides awaiting of <min_amount> of elements found by <selector> with
time limit = <limit>
"""
step = 1 # in seconds; sleep for 500ms
current_wait = 0
while current_wait < limit:
try:
print "Waiting... " + str(current_wait)
query = driver.find_elements_by_css_selector(selector)
if len(query) > min_amount:
print "Found!"
return True
else:
time.sleep(step)
current_wait += step
except:
time.sleep(step)
current_wait += step
return False
因为当前元素传递给此函数后,驱动程序(driver)会在DOM中丢失,所以这无法正常工作。 UL没有改变,但是由于某种原因Selenium无法再找到它。
3)显示等待。这太糟糕了,因为有些列表会立即加载,而有些则需要加载10多秒钟。如果我使用此技术,我必须在每个出现的最大时间内等待,这对我的情况非常不利。
4)我也无法正确地使用XPATH等待子元素。这只是期望ul出现。
try:
print "Going to nested list..."
#time.sleep(WAIT_TIME)
query = WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.XPATH, './/ul')))
nested_list = child.find_element_by_css_selector('ul')
请告诉我确保特定元素加载了多个后代元素的正确方法。
注:所有这些检查和搜索都应相对于当前元素进行。
if len(elements)>1:
,但您只传递了li
作为选择器,并使用物理驱动程序搜索元素。因此,它肯定会搜索整个文档吧?您应该首先获取ul
,然后在其中搜索。time.sleep()
调用。 - E.Z.