[英]Pycharm: Selenium with Python: Unable to find web elements using headless chrome
When I run the below code with headless chrome I'm facing issues while identifying the elements. 当我使用无头的chrome浏览器运行以下代码时,在识别元素时遇到了问题。 The same code runs just runs fine by commenting the below lines with head full mode. 通过以head full模式注释以下各行,可以运行相同的代码。
# chrome_options.add_argument('--headless') #chrome_options.add_argument('-headless')
# chrome_options.add_argument('--disable-gpu') #chrome_options.add_argument('-disable-gpu')
Test Details: 测试详情:
Operating system: Windows10 作业系统: Windows10
ChromeDriver: 75.0.3770.8 ChromeDriver: 75.0.3770.8
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
driver = webdriver.Chrome(ChromeDriverManager().install(), options=chrome_options)
wait = WebDriverWait(driver,30)
driver.maximize_window()
driver.get('https://learn.letskodeit.com/')
print(driver.title)
wait.until(EC.element_to_be_clickable((By.LINK_TEXT, 'Login'))).click()
wait.until(EC.visibility_of_element_located((By.ID, 'user_email'))).send_keys("test@email.com")
wait.until(EC.visibility_of_element_located((By.ID, 'user_password'))).send_keys("abcabc")
wait.until(EC.visibility_of_element_located((By.NAME, 'commit'))).click()
print(driver.title)
driver.close()
driver.quit()
Output: 输出:
"C:\Program Files (x86)\Python37-32\python.exe" C:/PycharmProjects/seleniumwd2/basics/RunHeadlessChromeTests.py
Checking for win32 chromedriver:75.0.3770.8 in cache
Driver found in C:\Users\vishr\.wdm\chromedriver\75.0.3770.8\win32/chromedriver.exe
Home | Let's Kode It
Traceback (most recent call last):
File "C:/PycharmProjects/seleniumwd2/basics/RunHeadlessChromeTests.py", line 15, in <module>
wait.until(EC.element_to_be_clickable((By.LINK_TEXT, 'Login'))).click()
File "C:\Users\vishr\AppData\Roaming\Python\Python37\site-packages\selenium\webdriver\support\wait.py", line 80, in until
raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
Process finished with exit code 1
for headless browser you have to set the window size to fire on event.Because headless browser can't recognise where to click without window size. 对于无头浏览器,您必须将窗口大小设置为在事件时触发。因为无头浏览器无法识别没有窗口大小的点击位置。
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('window-size=1920x1080')
driver = webdriver.Chrome(executable_path='path/to/chrome driver',options=chrome_options)
wait = WebDriverWait(driver,30)
driver.maximize_window()
driver.get('https://learn.letskodeit.com/')
print(driver.title)
wait.until(EC.element_to_be_clickable((By.LINK_TEXT, 'Login'))).click()
wait.until(EC.visibility_of_element_located((By.ID, 'user_email'))).send_keys("test@email.com")
wait.until(EC.visibility_of_element_located((By.ID, 'user_password'))).send_keys("abcabc")
wait.until(EC.visibility_of_element_located((By.NAME, 'commit'))).click()
print(driver.title)
driver.close()
driver.quit()
Printed output on console on headless mode. 在无头模式下在控制台上打印输出。
Home | Let's Kode It
Let's Kode It
You're clicking a button that loads another page. 您正在单击一个加载另一个页面的按钮。 You have to wait for the other page to load. 您必须等待其他页面加载。 This is tricky to get perfect. 要做到完美,这很棘手。
The easiest solution: 最简单的解决方案:
sleep(3)
The better solution using implicit waiting: 使用隐式等待的更好解决方案:
driver.implicitly_wait(3)
An even better solution using explicit waiting: 使用显式等待的更好解决方案:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
WebDriverWait(driver, 3).until(EC.presence_of_element_located((By.ID, "user_email")))
An even better better solution would be to catch exceptions, and layer all these solutions. 更好的解决方案是捕获异常,并将所有这些解决方案分层。
VISHVAMBRUTHJAVAGALTHIMMEGOWDA, VISHVAMBRUTHJAVAGALTHIMMEGOWDA,
I tried your code and was getting the same exception, First I thought that username was in Frame or iframe but it is not. 我尝试了您的代码,并遇到了相同的异常,首先,我认为用户名位于Frame或iframe中,但不是。
Then I tried to introduce webdriver wait and it worked just fine : 然后我尝试介绍webdriver wait,它工作得很好:
Code : 代码:
wait = WebDriverWait(driver,10)
driver.maximize_window()
driver.get("https://learn.letskodeit.com/")
print(driver.title)
driver.find_element_by_xpath("//a[contains(text(),'Login')]").click()
wait.until(EC.visibility_of_element_located((By.ID, 'user_email'))).send_keys("test@email.com")
#driver.find_element_by_id("user_email").
driver.find_element_by_id("user_password").send_keys("abcabc")
driver.find_element_by_name("commit").click()
print(driver.title)
Remember to imports these : 记住要导入这些:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
EDIT 1 : 编辑1:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
options = Options()
options.add_argument('--headless')
options.add_argument('--disable-gpu') # Last I checked this was necessary.
driver = webdriver.Chrome("C:/Users/XXXX/Downloads/BrowserDriver/chromedriver_win32/chromedriver.exe", chrome_options=options)
wait = WebDriverWait(driver,10)
driver.get("https://learn.letskodeit.com/")
print(driver.title)
wait.until(EC.element_to_be_clickable((By.LINK_TEXT, 'Login'))).click()
wait.until(EC.visibility_of_element_located((By.ID, 'user_email'))).send_keys("test@email.com")
wait.until(EC.visibility_of_element_located((By.ID, 'user_password'))).send_keys("abcabc")
wait.until(EC.visibility_of_element_located((By.NAME, 'commit'))).click()
print(driver.title)
To click()
on the element with text as Login you have to induce WebDriverWait for the element_to_be_clickable()
and you can use either of the following solutions: 要在文本为Login的元素上click()
,必须为element_to_be_clickable()
诱导WebDriverWait ,并且可以使用以下任一解决方案:
Using PARTIAL_LINK_TEXT
: 使用PARTIAL_LINK_TEXT
:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, "Login"))).click()
Using CSS_SELECTOR
: 使用CSS_SELECTOR
:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.navbar-link.fedora-navbar-link[href='/sign_in']"))).click()
Using XPATH
: 使用XPATH
:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@class='navbar-link fedora-navbar-link' and @href='/sign_in']"))).click()
Note : You have to add the following imports : 注意 :您必须添加以下导入:
from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.common.by import By from selenium.webdriver.support import expected_conditions as EC
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.