Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Selenium和Python:在select中显式等待回发(使用Selenium等待Javascript)_Javascript_Python_Selenium Webdriver - Fatal编程技术网

Selenium和Python:在select中显式等待回发(使用Selenium等待Javascript)

Selenium和Python:在select中显式等待回发(使用Selenium等待Javascript),javascript,python,selenium-webdriver,Javascript,Python,Selenium Webdriver,我正在尝试使用Python和Selenium选择列表中的各种元素。类在Javascript中附带了一个Postback,类似于: onchange="javascript:setTimeout('__doPostBack(\'dum1$dum2$dum3$ListBoxThingsToSelect\',\'\')', 0)" 当我尝试使用Selenium选择一个值时,它只对第一个值有效,然后DOM发生更改,我得到一个StaleElementReferenceException:Element不

我正在尝试使用Python和Selenium选择列表中的各种元素。
类在Javascript中附带了一个
Postback
,类似于:

onchange="javascript:setTimeout('__doPostBack(\'dum1$dum2$dum3$ListBoxThingsToSelect\',\'\')', 0)"
当我尝试使用Selenium选择一个值时,它只对第一个值有效,然后DOM发生更改,我得到一个
StaleElementReferenceException:Element不再附加到DOM
错误

因此,我尝试在单击该元素之前等待该元素变为可用。我使用以下代码和预期条件(EC)执行此操作:

这有时适用于选择多个值,但在某些情况下,可能无法单击(未单击该值),或者再次导致
StaleElementReferenceException:元素不再附加到DOM
错误。有人能帮忙吗?我的理论是select元素是可以定位和单击的,但是页面会继续加载,因为要加载的select元素更多。因此,DOM发生了变化,当我尝试
elem1.click()
时,DOM发生了变化

我如何等待整个字段被加载?
postback
的具体功能是什么? 很不幸我不能发布一个链接到页面,它是内部的

EDIT1

vals\u deselect
是我要取消选择的索引的索引列表。然后将这些索引粘贴到循环中的
XPATH
,以从select中选择特定选项。
vals\u deselect=[1,4,5,7,9,12]

EDIT2 我还尝试了以下方法:

print("jQuery.active: " + str(browser.execute_script("return jQuery.active")))
print("readyState: " + browser.execute_script("return document.readyState"))
WebDriverWait(browser, 100).until(EC.element_to_be_clickable((By.XPATH,
             "/html/body/form/div[11]/div[2]/fieldset/center/table/tbody/tr[3]/td[3]/select[2]/option[" + str(row)+ "]"))).click()
它总是显示
jquery.active
为0,而
readyState
complete
。我非常想解决这个问题。我想通过检查
readyState
jquery.active
可以检查回发是否完成。有人有什么想法吗

回发内容与此页面上的内容完全相同: 我需要等待它完成,但我该怎么做呢?

试试这个

from selenium.webdriver.common.action_chains import ActionChains

for row in vals_deselect:
        while not browser.execute_script("return document.readyState")== "complete":
            continue
        else:
            WebDriverWait(browser, 100).until(EC.element_to_be_clickable((
                By.XPATH, "/html/body/form/div[11]/div["
                          "2]/fieldset/center/table/tbody/tr[3]/td[3]/select["
                          "2]/option[" + str(row) + "]")))
            ActionChains(browser).move_to_element(elem1).click().perform()
如果每次选择选项后都会刷新
,则可以使用
预期条件。您还应该使用从
标记中选择一个选项

for row in vals_deselect:
    selectElement = driver.find_element_by_xpath("/html/body/form/div[11]/div[2]/fieldset/center/table/tbody/tr[3]/td[3]/select[2]")
    Select(selectElement).deselect_by_index(row)
    WebDriverWait(browser, 100).until(EC.staleness_of(selectElement))
作为旁注,您应该避免在
xpath
中使用绝对路径。尝试在html层次结构中为您要查找的元素找到尽可能接近的唯一标识符

更新

回答评论中的问题

你能给我解释一下这是怎么回事吗?元素变得陈旧这一事实是否意味着回发已经完成?另外,您能解释一下您对xpath的评论是什么意思吗

WebElement
在刷新或更改时会过时,这意味着即使它看起来完全相同(与您的情况类似)或已删除,也会有一个新元素。当整个DOM被刷新或更改时,或者仅当一个特定元素被刷新或更改时,就会发生这种情况
EC.
的staleness_将等待元素不再附加到DOM,或者直到定义的时间结束


有几个原因不使用绝对
xpath
。性能(比相对
xpath
或类似
find\u element\u by\u id
的方法慢得多)、可读性和脆弱性(想象有人在
之前添加了
标记。绝对
xpath
将失败,相对仍能工作)

你好,谢谢你的回答。My
vals\u deselect
是一个字符串列表,其中包含我希望取消选择的选项的文本。没有方法
get\u vals\u deselect()
。这可能是错误的原因吗?非常感谢您的帮助。您是说
vals\u deselectis
是一个静态列表吗?是的,它是。不应该吗?不可以,它包含字符串列表??你能举一个这个列表的例子吗?对不起,这是一个索引列表,指定要取消选择的选项。请看上面的EDIT1。我试过你的方法。但是我得到一个错误,声明
AttributeError:“Select”对象没有属性“已启用”
这是否意味着无法检查Select的过时性。此外,我还应该提到,我正在尝试按索引取消选择
,以防万一,最初列表中的所有值都被选中。@rashid我已经更新了答案。
select
deselect
的用法是一样的,这不是问题。这很有效。多谢各位。在我接受答案之前,请你向我解释一下这是怎么回事好吗?元素过时的事实是否意味着回发已经完成?另外,请您解释一下您对
xpath
的评论是什么意思?@rashid我在回答中添加了一个解释。太棒了,非常感谢。我接受了你的回答,把赏金交给了你。哈哈,我来之不易的名声消失了:),我只能在20小时内分配赏金。我会这样做。
for row in vals_deselect:
    selectElement = driver.find_element_by_xpath("/html/body/form/div[11]/div[2]/fieldset/center/table/tbody/tr[3]/td[3]/select[2]")
    Select(selectElement).deselect_by_index(row)
    WebDriverWait(browser, 100).until(EC.staleness_of(selectElement))