Вопрос-Ответ

How do you use EC.presence_of_element_located((By.ID, "myDynamicElement")) except to specify class not ID

Как вы используете EC.presence_of_element_located((By.ID, "myDynamicElement")), кроме как указывать класс без идентификатора

Я пытаюсь использовать Python для веб-очистки веб-сайта, который динамически загружает свой HTML-код с помощью встроенных файлов javascript, которые отображают данные в виде ответа в HTML. Следовательно, если я использую только BeautifulSoup, я не смогу получить те данные, которые мне нужны, поскольку моя программа очистит их до того, как Javascript загрузит данные. В связи с этим я интегрирую библиотеку selenium в свой код, чтобы заставить мою программу ждать, пока определенный элемент не будет найден, прежде чем она очистит веб-сайт.

Я изначально сделал это:

element = WebDriverWait(driver,100).until(EC.presence_of_element_located((By.ID, "tabla_evolucion")))

Но вместо этого я хочу указать класс, выполнив что-то вроде:

element = WebDriverWait(driver,100).until(EC.presence_of_element_located((By.class, "ng-binding ng-scope")))  

Вот остальная часть моего кода:

driver_path = 'C:/webDrivers/chromedriver.exe'
driver = webdriver.Chrome(executable_path=driver_path)
driver.header_overrides = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36'}
url = "myurlthatIamscraping.com"
response = driver.get(url)
html = driver.page_source
characters = len(html)
element = WebDriverWait(driver,100).until(EC.presence_of_element_located((By.class, "ng-binding ng-scope")))

print(html)
print(characters)
time.sleep(10)
driver.quit()

У меня это не работает, и я нигде не могу найти правильный синтаксис.

Переведено автоматически
Ответ 1

Соответствующий HTML помог бы нам создать более канонический ответ. Однако начнем с вашей первой строки кода:

element = WebDriverWait(driver,100).until(EC.presence_of_element_located(
(By.ID, "tabla_evolucion")))

в значительной степени законно использовать where в качестве второй строки кода:

element = WebDriverWait(driver,100).until(EC.presence_of_element_located(
(By.class, "ng-binding ng-scope")))

Выдаст ошибку как:


Сообщение: недопустимый селектор: составные имена классов не разрешены


поскольку вы не можете передать несколько классов через By.class.


Вы можете найти подробное обсуждение в Недопустимый селектор: не разрешены составные имена классов с использованием find_element_by_class_name с Webdriver и Python



Решение

Вам нужно позаботиться о нескольких вещах следующим образом:


  • Без какой-либо видимости для вашей базы данных, функционально вызывая WebDriverWait в сочетании с EC as presence_of_element_located() просто подтверждает присутствие элемента в дереве DOM. Предположительно, в дальнейшем вам нужно либо получить атрибуты, например, value, innerText и т.д., Либо вы будете взаимодействовать с элементом. Итак, вместо presence_of_element_located() вам нужно использовать либо visibility_of_element_located(), либо element_to_be_clickable()


Подробное обсуждение можно найти в WebDriverWait, который работает не так, как ожидалось



  • Для достижения оптимального результата вы можете объединить атрибуты ID и CLASS и использовать любую из следующих стратегий поиска:



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



  element = WebDriverWait(driver, 20).until(EC.visibility_of_element_located(
(By.CSS_SELECTOR, ".ng-binding.ng-scope#tabla_evolucion")))

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

  element = WebDriverWait(driver, 20).until(EC.visibility_of_element_located(
(By.XPATH, "//*[@class='ng-binding ng-scope' and @id='tabla_evolucion']")))
Ответ 2

Это есть в документации.


Набор поддерживаемых стратегий локализации.
ИМЯ_КЛАССА = 'имя класса'
CSS_SELECTOR = 'css-селектор'
ID = 'id'
LINK_TEXT = 'текст ссылки'
NAME = 'имя'
PARTIAL_LINK_TEXT = 'частичный текст ссылки'
ИМЯ_ТЕГА = 'имя тега'
XPATH = 'xpath'


Примечание: То, что у вас есть в вашем коде, - это не класс, это два класса. Это не сработает, если вы используете By.CLASS_NAME() потому что он ожидает только один класс. Вместо этого вам нужен CSS-селектор.

EC.presence_of_element_located((By.CSS_SELECTOR, ".ng-binding.ng-scope")))

В синтаксисе селектора CSS a . указывает класс. Смотрите Документы W3C для получения дополнительной информации о синтаксисе селектора CSS.

Ответ 3

У меня есть решение, попробуйте это - измените свой класс class на CLASS_NAME

element = WebDriverWait(driver,100).until(EC.presence_of_element_located((By.CLASS_NAME , "ng-binding ng-scope")))
Ответ 4

попробуйте следующее :

element = WebDriverWait(driver,100).until(EC.presence_of_element_located((By.CLASS_NAME, "ng-binding")))

или

element = WebDriverWait(driver,100).until(EC.presence_of_element_located((By.CLASS_NAME, "ng-scope")))

Следует упомянуть одну вещь: вы пытаетесь передать два имени классов, т.е. ng-binding - это один класс, а ng-scope - другой.

2023-04-24 22:11 python selenium selenium-webdriver