Python - selenium. Не получается аплоуднуть изображение в input[type='file']
На странице используется фреймворк vuesax: https://lusaxweb.github.io/vuesax/components/upload.html#default
При выполнении функции self.element_is_visible(self.locators.UPL_FILE).send_keys(rf"C:\Users\user\PycharmProjects\Project\files\jpeg.jpeg")
где UPL_FILE:
UPL_FILE = (By.CSS_SELECTOR, "input[type='file']")
Уходит в таймаут, ощущение что он не видит инпута.
На https://demoqa.com/upload-download данная функция срабатывает.
Подскажите, может переключиться на фрейм, или есть другие варианты грузануть изображение в инпут?
Фото:
Ответы (2 шт):
Да, вы правильно заметили, что input не реагирует на click(). Так делают когда хотят привязать событие через JavaScript к input, но чтоб для пользователя он выглядел стандартно. Поэтому клик привязали к родительскому div, это видно в отладчике хром. Из-за нестандартной работы input, мы не можем передать строку с путем к файлу через .send_keys, пришлось использовать библиотеку для управления клавиатурой keyboard. С PyAutoGUI под виндоус 10 у меня не получилось.
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
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
import keyboard
url = 'https://lusaxweb.github.io/vuesax/components/upload.html#default'
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get(url)
try:
# Ждем пока элемент станет кликабельным или выбрасываем исключение по времени.
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.CSS_SELECTOR, "div[class='con-input-upload']")))
element.click()
# Ждем пока откроется окно с выбором файла.
time.sleep(10)
# Заполняем поле ввода пути и жмем на Enter.
keyboard.write(r"C:\Users\ф\Desktop\Лазурная схема.jpg")
keyboard.press('enter')
# Дальше вам надо найти кнопку "загрузить файл" и кликнуть по ней.
finally:
time.sleep(5)
driver.quit()
Дальше дело за вами, если будут трудности создавайте новый вопрос.
p.s. Мои выводы о работе данного блока не верные, более "чистое" решение в другом ответе Steenkle.
В итоге мешал opacity, селениум не видит инпута, пришлось посовокупляться пару дней))
driver.execute_script("for (const [key, value] of Object.entries(document.getElementsByTagName('input'))) {value.setAttribute('style', 'opacity: 1') }")
В итоге скрипт присваивает opacity значение 1, тем самым получаем чистый инпут:
https://prnt.sc/pym3lJIMkbMw
в который сработает send_keys, и можно будет аплоуднуть документ. Всем спасибо за внимание)
Полный код:
import time
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
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
def disable_opacity():
""" disable all opacity in input[type='file'] """
return driver.execute_script("for (const [key, value] of Object.entries(document.getElementsByTagName('input'))) { value.setAttribute('style', 'opacity: 1') }")
def upl_file():
file = rf'C:\Users\user\PycharmProjects\project\example.jpeg'
upl_btn = driver.find_element(By.XPATH, "//input[@type='file']")
upl_btn.send_keys(file)
url = 'https://lusaxweb.github.io/vuesax/components/upload.html#default'
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get(url)
disable_opacity()
time.sleep(2) # Видим что появилась кнопка
upl_file()
time.sleep(5) # Видим что изображение загрузилось
driver.quit()
if __name__ == '__main__':
pass