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

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

Изначально я сделал это:

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

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


person Rishi Vadaga    schedule 29.07.2019    source источник
comment
Можете ли вы опубликовать свой источник html и пример на Python для более быстрого ответа.   -  person Sureshmani Kalirajan    schedule 30.07.2019
comment
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, например 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 ( символы) time.sleep (10) driver.quit ()   -  person Rishi Vadaga    schedule 30.07.2019
comment
Извините, я не знаю, как отформатировать код в стеке   -  person Rishi Vadaga    schedule 30.07.2019
comment
Если вы можете опубликовать исходный код html для элемента, который вы ищете, вероятно, вы получите лучший ответ. Вы хотите дождаться какого-либо конкретного элемента на странице? тогда вы можете подождать, используя любой локатор элементов - id, class или xpath и т. д.   -  person Sureshmani Kalirajan    schedule 30.07.2019


Ответы (4)


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

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

Вызовет ошибку как:

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

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

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


Решение

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

  • Без какой-либо видимости вашего варианта использования, функциональное включение WebDriverWait в сочетании с EC как 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']")))
person DebanjanB    schedule 01.08.2019
comment
@LeoMa Ответы на ваши сомнения 1) By.class: Если вы внимательно прочитаете ответ, я сослался на него из испытаний кода OP и не является частью решения, которое я предложил. 2) Вы должны соблюдать максимальную осторожность при редактировании вопросов / ответов в отношении орфографии и грамматики, поскольку вы неправильно набрали answe вместо answer. - person DebanjanB; 23.01.2020

Он находится в документации.

Набор поддерживаемых стратегий локатора.
CLASS_NAME = 'имя класса'
CSS_SELECTOR = 'css selector'
ID = 'id'
LINK_TEXT = 'текст ссылки'
NAME = 'name' < br> PARTIAL_LINK_TEXT = 'частичный текст ссылки'
TAG_NAME = 'имя тега'
XPATH = 'xpath'

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

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

В синтаксисе селектора CSS . обозначает класс. Дополнительную информацию о синтаксисе селектора CSS см. В документации W3C.

person JeffC    schedule 30.07.2019

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

element = WebDriverWait(driver,100).until(EC.presence_of_element_located((By.CLASS_NAME , "ng-binding ng-scope")))
person Abhishek kumar    schedule 10.03.2021

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

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

or

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

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

person Atique    schedule 19.05.2021