python - Selenium 仅在使用无头铬(Python)时无法定位元素
问题描述
我刚开始学习 Selenium,需要使用云中的 jenkins 机器验证登录网页,该机器没有 GUI。我设法在具有 UI 的系统上成功运行脚本。但是,当我修改脚本以无头运行时,无法找到元素。我的脚本如下:
#!/usr/bin/env python3
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from webdriver_manager.chrome import ChromeDriverManager
import time
import argparse
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--window-size=1120, 550')
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--allow-running-insecure-content')
driver = webdriver.Chrome(ChromeDriverManager().install(), chrome_options=chrome_options)
driver.implicitly_wait(5)
lhip = '13.14.15.16'
user = 'username'
paswd = 'password'
parser = argparse.ArgumentParser()
parser.add_argument('-i', '--lh_ip', type=str, metavar='', default=lhip, help='Public IP of VM' )
parser.add_argument('-u', '--usr', type=str, metavar='', default=user, help='Username for VM')
parser.add_argument('-p', '--pwd', type=str, metavar='', default=paswd, help='Password for VM')
args = parser.parse_args()
lh_url = 'https://' + args.lh_ip + '/login/'
driver.get(lh_url)
try:
if driver.title == 'Privacy error':
driver.find_element_by_id('details-button').click()
driver.find_element_by_id('proceed-link').click()
except:
pass
driver.find_element_by_id('username').send_keys(args.usr)
driver.find_element_by_id('password').send_keys(args.pwd)
driver.find_element_by_id('login-btn').click()
driver.implicitly_wait(10)
try:
if driver.find_element_by_tag_name('span'):
print('Login Failed')
except:
print('Login Successful')
driver.close()
在没有 chrome_options 的情况下使用 python 脚本在我的系统上运行良好。但是,在将它们添加到无头模式下运行时,它会失败并显示以下输出:
[WDM] - Current google-chrome version is 85.0.4183
[WDM] - Get LATEST driver version for 85.0.4183
[WDM] - Driver [/home/ramesh/.wdm/drivers/chromedriver/linux64/85.0.4183.87/chromedriver] found in cache
Traceback (most recent call last):
File "/home/ramesh/practice_python/test_headless.py", line 44, in <module>
driver.find_element_by_id('username').send_keys(args.usr)
File "/home/ramesh/.local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 360, in find_element_by_id
return self.find_element(by=By.ID, value=id_)
File "/home/ramesh/.local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 978, in find_element
'value': value})['value']
File "/home/ramesh/.local/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 321, in execute
self.error_handler.check_response(response)
File "/home/ramesh/.local/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 242, in check_response
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="username"]"}
(Session info: headless chrome=85.0.4183.121)
由于我大约有一天学习 Selenium,我可能会做一些相当愚蠢的事情,所以如果有人告诉我我做错了什么,我将不胜感激。我用谷歌搜索了很多东西,尝试了很多东西,但都没有奏效。另外,当我只使用 id 作为用户名时,为什么会说“css 选择器”?
解决方案
如果脚本在没有无头模式的情况下运行良好,则可能是窗口大小存在问题。除了指定 --no-sandbox 选项,尝试更改传递给 webdriver 的窗口大小
chrome_options.add_argument('--window-size=1920,1080')
这个窗口大小在我的情况下有效。
即使这不起作用,您也可能需要添加等待计时器,因为与 UI 模式下的浏览器相比,无头模式下的渲染以不同的方式工作。
参考无头模式渲染 - https://www.toolsqa.com/selenium-webdriver/selenium-headless-browser-testing/
推荐阅读
- python - 最后一个字符不打印
- reactjs - 如何提高 Material UI 整体动画速度
- python - 想知道 Scikit-Learn 中的编码算法
- java - 带有 sslSocketFactory 的 Okhttp.Builder 中的 ExceptionInInitializerError
- angular - 如何仅从 Angular 6 中的 http 请求中获取特定字段
- jquery - Jquery Append 不工作;“请删除换行符并编码小于字符...”在 F12 处引发错误
- python - 使用 Keras 对 3 个类进行图像分类仅返回一个值而不是 1 X 3 数组
- python - OpenCV 绘制轮廓错误断言失败
- android - 在 kotlin 中创建对象的语法有些模糊?
- codeigniter - 重定向时没有删除 index.php - codeigniter