一尘不染

没有这样的元素:无法在生产环境中使用chromedriver和Selenium定位元素

selenium

seleniumchromedriver出现问题,我无法弄清楚是什么原因造成的。几周前,一切正常,突然开始出现此错误。问题来自以下功能。

 def login_(browser):
    try:
        browser.get("some_url")
        # user credentials
        user = browser.find_element_by_xpath('//*[@id="username"]')
        user.send_keys(config('user'))
        password = browser.find_element_by_xpath('//*[@id="password"]')
        password.send_keys(config('pass'))
        login = browser.find_element_by_xpath('/html/body/div[1]/div/button')
        login.send_keys("\n")
        time.sleep(1)
        sidebar = browser.find_element_by_xpath('//*[@id="sidebar"]/ul/li[1]/a')
        sidebar.send_keys("\n")
        app_submit = browser.find_element_by_xpath('//*[@id="sidebar"]/ul/li[1]/ul/li[1]/a')
        app_submit.send_keys("\n")
    except TimeoutException or NoSuchElementException:
        raise LoginException

此功能在开发环境(macOS 10.11)中正常工作,但是在生产环境中引发以下错误:

Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[@id="sidebar"]/ul/li[1]/a"}
(Session info: headless chrome=67.0.3396.79)
(Driver info: chromedriver=2.40.565383 (76257d1ab79276b2d53ee97XXX),platform=Linux 4.4.0-116-generic x86_64)

我已经在每个环境中都更新了Chrome和chromedriver(分别为v67和2.40)。我还给了它更多time.sleep(15)。但是问题仍然存在。我的最新猜测是,webdriver的初始化可能无法正常工作:

def initiate_webdriver():
   option = webdriver.ChromeOptions()
   option.binary_location = config('GOOGLE_CHROME_BIN')
   option.add_argument('--disable-gpu')
   option.add_argument('window-size=1600,900')
   option.add_argument('--no-sandbox')
   if not config('DEBUG', cast=bool):
       display = Display(visible=0, size=(1600, 900))
       display.start()
       option.add_argument("--headless")
   else:
       option.add_argument("--incognito")
   return webdriver.Chrome(executable_path=config('CHROMEDRIVER_PATH'), chrome_options=option)

因为,如果该按钮Display不起作用,则可能没有提到的sidebar而是其他按钮。

所以我的问题是:有人遇到过类似的问题吗?有没有办法知道驾驶员正在寻找这样的元素时页面显示什么?


阅读 212

收藏
2020-06-26

共1个答案

一尘不染

根据该login_(browser)方法的几件事:

  • 通过以下方式确定“ 登录” 按钮后:
    login = browser.find_element_by_xpath('/html/body/div[1]/div/button')
    

我建议,而调用send_keys("\n")该采取帮助的onclick()通过事件login.click()嘲笑 登录按钮的点击 如下:

    login = browser.find_element_by_xpath('/html/body/div[1]/div/button')
login.click()
  • 接下来,当您确定 侧边栏时, 诱导 WebDriverWait 使 元素可单击 ,如下所示:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="sidebar"]/ul/li[1]/a'))).click()
    
  • 正如您提到的那样, 您的代码块在 macOS 10.11 环境中可以完美运行,但在生产环境(Linux)中_会 _引发以下错误, 很可能是不同的浏览器在不同的OS体系结构中以不同的方式呈现 HTML DOM 。因此,必须使用 相对xpath 而不是 绝对 xpath ,如下所示:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@attribute='value']"))).click()
    

根据该initiate_webdriver()方法的几件事:

  • 根据 无头Chrome入门, 该参数--disable-gpu仅适用于 Windows ,不适用于 Linux OS 的有效配置。因此需要删除:
    option.add_argument('--disable-gpu')
    

注意 :您必须添加以下导入:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
2020-06-26