Selenium查找稍后通过javascript加载的元素

Selenium查找稍后通过javascript加载的元素,javascript,python,html,selenium,Javascript,Python,Html,Selenium,所以我尝试使用selenium来自动完成一些表单,但我遇到了一个问题。我使用的其中一个表单不是直接由HTML加载的,而是在页面正常加载后使用JavaScript加载的。无论出于何种原因,selenium在加载javascript后都无法看到页面的更新源。例如,如果我运行以下代码 browser = webdriver.Firefox() browser.get('https://examplepage.com') WebDriverWait(browser, 20).until(EC.elem

所以我尝试使用selenium来自动完成一些表单,但我遇到了一个问题。我使用的其中一个表单不是直接由HTML加载的,而是在页面正常加载后使用JavaScript加载的。无论出于何种原因,selenium在加载javascript后都无法看到页面的更新源。例如,如果我运行以下代码

browser = webdriver.Firefox()
browser.get('https://examplepage.com')

WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.ID, “13jres”))).send_keys(“email@email.com”)
什么事也没发生,它就超时了。在做了一些测试之后,我注意到如果我用python打印源代码,使用以下代码

browser = webdriver.Firefox()
browser.get('https://examplepage.com')
time.sleep(20)
print browser.page_source
然后,源代码与我可以在selenium firefox实例中手动查看的源代码不同。因此,根据selenium source输出,下面这一行是我试图输入的内容,虽然在检查firefox中的元素或查看使用selenium加载的firefox实例中的源代码时,它显然不在那里

<input label=“Email” type="text" name="13jres" id="13jres" class="text-field”>(shortened to make it more readable)

正如您所提到的
没有发生任何事情,它会超时。
这本质上意味着它可以是以下情况之一:

  • 标记:根据您提供的缩写HTML

    <input label=“Email” type="text" name="13jres" id="13jres" class="text-field”>(shortened to make it more readable)
    
    我们是否调用了右侧webelement上的
    send_keys()
    ,仍然没有定论

  • 定位器策略
    :根据您的代码试用,您已尝试使用基于
    id的定位器策略
    。但是设置为value13jres
    id
    属性在我看来是动态的。因此,您可以更精细,采用更有效的定位策略,如下所示:

    WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, “input.text-field[id$='jres']”))).send_keys(“email@email.com”)
    
  • 您可以在中找到有关定位器策略的详细讨论


尝试等待页面完全加载,然后执行操作。我不在python中使用,但在javascriptexecutor中有一个选项

bool wait = new WebDriverWait(driver, TimeSpan.FromSeconds(60)).Until(d => ((javascriptexecutor)d).executescript("return document.readyState").Equals("complete")); 

if(wait == true)
{
    //Your code
}
python的上述语法可能会更改


上述代码将等待页面加载60秒,如果页面已准备就绪(60秒内),则返回true;如果页面未准备就绪(60秒后),则返回false。

根据
page\u source
中的源代码使用selenium自动化可能是一种不好的做法,因为有两种主要情况,而且经常发生,如果live页面背后的代码与初始网页源页面不同:

1.
page\u source
显示源页面,但源页面虽然实际上是的原始种子页面,但可以更改,并且有时会被JS代码动态更改。 在这种情况下,est实践将是:

browser.get("url")
sleep(experimental) # usually get will finish only after the page is loaded but sometimes there is some JS woo running after on load time
  
try:
    element= WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.ID, 'your_id_of_interest')))
    print "element is ready do the thing!"
except TimeoutException:
    print "Somethings wrong!"   
2.
page\u source
不会显示,如果您碰巧看到其中的元素,则它将在JavaScript中的
page\u source
浏览器
、或
文档
对象中不可见。您需要首先展开阴影DOM

def expand_shadow_element(element):
  shadow_root = driver.execute_script('return arguments[0].shadowRoot', element)
  return shadow_root

outer = expand_shadow_element(driver.find_element_by_css_selector("#test_button"))
inner = outer.find_element_by_id("inner_button")
inner.click()
当您在shadow root中有shadow root时,问题就会出现。要查看更多详细信息,请查看以下答案:


如果你想知道如何获取动态内容的源代码,你也可以看到我给出的答案:

在你睡了20秒后,
find_element_by_id(“13jres”)
返回什么?在Firefox控制台中,
document.getElementById(“13jres”)
返回什么?加载页面时是否调用javascript?试试这个
EC.visibility\u of_element\u located((By.ID,“13jres”))
。回答得好,你真的详细了等待+1
def expand_shadow_element(element):
  shadow_root = driver.execute_script('return arguments[0].shadowRoot', element)
  return shadow_root

outer = expand_shadow_element(driver.find_element_by_css_selector("#test_button"))
inner = outer.find_element_by_id("inner_button")
inner.click()