所以我试图使用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源输出不存在,即使它显然在那里检查firefox中的元素或在Firefox实例中查看已加载的内容使用硒。
<input label=“Email” type="text" name="13jres" id="13jres" class="text-field”>(shortened to make it more readable)
通过阅读一些文档,我在引用page_source命令时发现了这一点,我想这解释了源代码的不同之处,但我仍然不清楚如何在页面上找到这些元素来缓解我的问题。我在selenium(safari,chrome等)中尝试过其他浏览器,但除此之外,我不确定我需要做什么。
“如果页面在加载后已被修改(例如,通过Javascript),则无法保证返回的文本是已修改页面的文本。请参阅用于确定返回文本是否反映网页当前状态或Web服务器最后发送的文本的特定驱动程序的文档。“
答案 0 :(得分:2)
正如您所提到的Nothing happens and it times out.
,这实际上意味着它可以是以下任何一种情况:
<input>
代码:根据您提供的 缩短的HTML :
<input label=“Email” type="text" name="13jres" id="13jres" class="text-field”>(shortened to make it more readable)
由于缩短了标记,我们无法理解<input>
标记是否包含与之关联的onClick()
事件。
接下来你正试图:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.ID, “13jres”))).send_keys(“email@email.com”)
我们是否在右侧 webelement 上调用send_keys()
仍未确定。
Locator Strategy
:根据您的代码试用版,您尝试使用基于id
的定位器策略。但id
属性设置为值 13jres 对我来说看起来很动态。因此,您可以更精细地调整更有效的Locator Strategy
,如下所示:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, “input.text-field[id$='jres']”))).send_keys(“email@email.com”)
答案 1 :(得分:1)
基于来自page_source
的源代码使用selenium进行自动化可能是不好的做法,因为有两种主要情况,并且它们经常发生,其中实时页面背后的代码与初始网页源页面不同:< / p>
page_source
显示源页面,但源页面虽然实际上是DOM
的原始种子页面,DOM
可以更改,但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!"
page_source
未显示shadow DOMS如果您在shadow DOMS中看到该元素,则page_source
,browser
或{{ 1}} JavaScript中的对象需要先扩展shadow-DOM
document
如果您在影子根中有影子根以查看更多详细信息,则会出现问题,请参阅此答案:Accessing Shadow DOM tree with Selenium
如果您想了解如何获取动态内容的源代码,您还可以看到我给出的答案:https://stackoverflow.com/a/48782708/1577343
答案 2 :(得分:0)
尝试等待页面完全加载然后执行操作。我不是在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。