Pycharm: Selenium with Python: невозможно найти веб-элементы, используя хром без головы - PullRequest
0 голосов
/ 12 июня 2019

Когда я запускаю приведенный ниже код без хрома, у меня возникают проблемы при определении элементов.Тот же код выполняется просто отлично, комментируя следующие строки с полным режимом заголовка.

# chrome_options.add_argument ('- headless')

# chrome_options.add_argument ('- disable-gpu')

Детали теста:

Операционная система: Windows10

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()

Вывод:

"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

Ответы [ 4 ]

1 голос
/ 12 июня 2019

для безголового браузера вы должны установить размер окна для запуска при событии. Потому что безголовый браузер не может распознать, где нажимать без размера окна.

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()

Вывод на консоль в режиме без головы.

Home | Let's Kode It
Let's Kode It
0 голосов
/ 12 июня 2019

VISHVAMBRUTHJAVAGALTHIMMEGOWDA,

Я попробовал ваш код и получил то же исключение. Сначала я подумал, что имя пользователя находится в Frame или iframe но это не так.

Затем я попытался ввести ожидание веб-драйвера, и оно работало просто отлично:

Код:

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)  

Не забудьте импортировать эти:

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

РЕДАКТ. 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)
0 голосов
/ 12 июня 2019

К click() для элемента с текстом Логин вы должны WebDriverWait для element_to_be_clickable(), и вы можете использовать любое из следующих решений:

  • Использование PARTIAL_LINK_TEXT:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, "Login"))).click()
    
  • Использование CSS_SELECTOR:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.navbar-link.fedora-navbar-link[href='/sign_in']"))).click()
    
  • Использование XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[@class='navbar-link fedora-navbar-link' and @href='/sign_in']"))).click()
    
  • Примечание : Вы должны добавить следующий импорт:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    
0 голосов
/ 12 июня 2019

Вы нажимаете кнопку, которая загружает другую страницу.Вам нужно дождаться загрузки другой страницы.Это сложно сделать идеальным.

Самое простое решение:

sleep(3)

Лучшее решение с использованием неявного ожидания:

driver.implicitly_wait(3)

Еще лучшее решение с использованием явного ожидания:

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")))

Еще лучшим решением было бы перехват исключений и наложение всех этих решений.

...