动态生成的元素-NoSuchElementException:消息:没有这样的元素:无法找到元素?

时间:2020-04-19 02:08:05

标签: python selenium

我无法在Linkedin页面上选择加载更多按钮。我在找到xpath时收到此错误:selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element

我怀疑问题是该按钮当时在页面上不可见。因此,我尝试了actions.move_to_element。但是,页面滚动到元素的正下方,因此该元素不再可见,并且随后发生相同的错误。

我也尝试过move_to_element_with_offset,但这并没有改变页面滚动到的位置。

如何滚动到页面上的正确位置,以便可以成功选择元素?

我的相关代码:

import parameters
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver

ChromeOptions = webdriver.ChromeOptions()
driver = webdriver.Chrome('C:\\Users\\Root\\Downloads\\chromedriver.exe')

driver.get('https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin')
sleep(0.5)

username = driver.find_element_by_name('session_key')

username.send_keys(parameters.linkedin_username)
sleep(0.5)

password = driver.find_element_by_name('session_password')
password.send_keys(parameters.linkedin_password)
sleep(0.5)

sign_in_button = driver.find_element_by_xpath('//button[@class="btn__primary--large from__button--floating"]')
sign_in_button.click()

driver.get('https://www.linkedin.com/in/kate-yun-yi-wang-054977127/?originalSubdomain=hk')

loadmore_skills=driver.find_element_by_xpath('//button[@class="pv-profile-section__card-action-bar pv-skills-section__additional-skills artdeco-container-card-action-bar artdeco-button artdeco-button--tertiary artdeco-button--3 artdeco-button--fluid"]')

actions = ActionChains(driver)
actions.move_to_element(loadmore_skills).perform()
#actions.move_to_element_with_offset(loadmore_skills, 0, 0).perform()
loadmore_skills.click()

3 个答案:

答案 0 :(得分:1)

玩弄它之后,我似乎已经弄清楚了问题的根源。错误

selenium.common.exceptions.NoSuchElementException:消息:没有这样的元素:无法找到元素:{“方法”:“ xpath”,“选择器”:” //按钮[@ class =“ pv-profile-section__card-动作栏pv技能部分____________________其他技能artdeco容器卡动作栏artdeco按钮artdeco按钮-第三artdeco按钮-3 artdeco按钮-流体“]”} (会话信息:chrome = 81.0.4044.113)

始终正确指出遇到的问题,因此无法找到该元素。可能的原因包括:

  • 执行时不存在的元素
  • 动态生成
  • 内容名称冲突

在您的情况下,这是第二点。当您向下滚动时,显示的内容将动态加载。因此,当它第一次加载您的个人资料时,技能部分实际上不在DOM中。因此,要解决此问题,只需滚动至该部分,即可将其应用于DOM。

这条线是这里的把戏。它将放置在正确的面板上,从而将数据加载并应用到DOM。

driver.execute_script("window.scrollTo(0, 1800)")

这是我的代码(请根据需要更改)

from time import sleep

# import parameters
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait

ChromeOptions = webdriver.ChromeOptions()
driver = webdriver.Chrome('../chromedriver.exe')

driver.get('https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin')
sleep(0.5)

username = driver.find_element_by_name('session_key')

username.send_keys('')
sleep(0.5)

password = driver.find_element_by_name('session_password')
password.send_keys('')
sleep(0.5)

sign_in_button = driver.find_element_by_xpath('//button[@class="btn__primary--large from__button--floating"]')
sign_in_button.click()


driver.get('https://www.linkedin.com/in/kate-yun-yi-wang-054977127/?originalSubdomain=hk')

sleep(3)
# driver.execute_script("window.scrollTo(0, 1800)")
sleep(3)
loadmore_skills=driver.find_element_by_xpath('//button[@class="pv-profile-section__card-action-bar pv-skills-section__additional-skills artdeco-container-card-action-bar artdeco-button artdeco-button--tertiary artdeco-button--3 artdeco-button--fluid"]')


actions = ActionChains(driver)
actions.move_to_element(loadmore_skills).perform()
#actions.move_to_element_with_offset(loadmore_skills, 0, 0).perform()
loadmore_skills.click()

输出

data-*

更新

关于较新的问题,您需要实现一个连续滚动方法,该方法使您能够动态更新skills部分。这需要进行很多更改,理想情况下,应将其作为另一个问题进行询问。

我还找到了一种简单的解决方案,将滚动条设置为正确的阈值。因为y=3200对于我检查过的所有个人资料(包括您的,我的和其他一些个人资料)似乎都可以正常工作。

driver.execute_script("window.scrollTo(0, 3200)")

答案 1 :(得分:0)

如果按钮在加载时在页面上不可见,则使用until方法来延迟执行

try:
    myElem = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.ID, 'IdOfMyElement')))
    print "Button is rdy!"
except TimeoutException:
    print "Loading took too much time!"

示例取自here

要获取元素的确切位置,可以使用以下方法。

element = driver.find_element_by_id('some_id')
element.location_once_scrolled_into_view

这实际上是要向您返回页面上元素的坐标(xy),但也向下滚动到目标元素。然后,您可以使用坐标单击按钮。您可以阅读有关here的更多信息。

答案 2 :(得分:0)

当我们在硒程序代码中提到的定位符(即id / xpath / name / class_name / css选择器等)找不到网页上的Web元素时,您将收到NoSuchElementException错误。

如何解决NoSuchElementException:

  1. 应用WebDriverWait:允许Webdriver等待特定时间
  2. 尝试拦截块

因此,在对Webelement执行操作之前,您需要考虑Web元素,我已经删除了多余的代码,并且避免使用硬编码的等待,因为它不是处理同步问题的好习惯。同样,在单击“显示更多”按钮时,您必须向下滚动,否则将无法工作。

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains


driver = webdriver.Chrome(executable_path="path of chromedriver.exe")

driver.get('https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin')
driver.maximize_window()

WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.NAME, "session_key"))).send_keys("email id")
WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.NAME, "session_password"))).send_keys("password ")
WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//button[@class='btn__primary--large from__button--floating']"))).click()

driver.get("https://www.linkedin.com/in/kate-yun-yi-wang-054977127/?originalSubdomain=hk")
driver.maximize_window()

driver.execute_script("scroll(0, 250);")
buttonClick = WebDriverWait(driver, 10).until(
    EC.element_to_be_clickable((By.XPATH, "//span[text()='Show more']")))
ActionChains(driver).move_to_element(buttonClick).click().perform()

输出:

enter image description here