Как получить элемент после его изменения в селене? - PullRequest
1 голос
/ 01 декабря 2019

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

Я пытаюсь найти кликабельный элемент на странице, сохранить его и родительский элемент, щелкнуть элемент и затем найти его через родительский элемент, но я не могу 'сделать это:

>>> phone = driver.find_element_by_xpath('.//a[contains(@class, "link-phone")]')
>>> phone.get_attribute('innerHTML')
'\n                    <span class="glyphicon glyphicon-phone"></span>Показать телефон'
>>> phone_elem = phone.find_element_by_xpath('..')
>>> phone_elem.get_attribute('innerHTML')
'<a class="link-phone nowrap js-get-phone" href="javascript:void(0);">\n                    <span class="glyphicon glyphicon-phone"></span>Показать телефон</a> '
>>> ActionChains(driver).move_to_element(phone).perform()
>>> sleep(0.5)
>>> phone.click()
>>> sleep(1.5)
>>> phone_elem.get_attribute('innerHTML')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Python37\lib\site-packages\selenium\webdriver\remote\webelement.py", line 141, in get_attribute
    self, name)
  File "C:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 636, in execute_script
    'args': converted_args})['value']
  File "C:\Python37\lib\site-packages\selenium\webdriver\remote\webdriver.py", line 321, in execute
    self.error_handler.check_response(response)
  File "C:\Python37\lib\site-packages\selenium\webdriver\remote\errorhandler.py", line 242, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.StaleElementReferenceException: Message: stale element reference: element is not attached to the page document
  (Session info: chrome=79.0.3945.56)

>>>                                                                                                                                                                                              

Скорее всего, после нажатия на элемент вся страница изменится. Что я могу сделать?

1 Ответ

1 голос
/ 01 декабря 2019

Чтобы извлечь телефонные номера, сначала нужно scrollIntoView элемент, а затем WebDriverWait для element_to_be_clickable(), и вы можете использовать следующие Стратегии локатора :

  • Кодовый блок:

    driver.get('https://www.work.ua/ru/jobs/3385738/')
    driver.execute_script("return arguments[0].scrollIntoView(true);", WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//p/b[text()='Условия:']"))))
    WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//a[@class='link-phone nowrap js-get-phone']"))).click()
    print([my_elem.get_attribute("innerHTML") for my_elem in WebDriverWait(driver, 5).until(EC.visibility_of_all_elements_located((By.XPATH, "//p/b[text()='Для связи с нами обращайтесь по номеру:']//following::p/b[contains(., '—')]")))])
    driver.quit()
    
  • Консольный вывод:

    ['+380 (93) 908 — 53 — 66 ', '+380 (93) — 103 — 19 — 77 ']
    
  • Примечание : необходимо добавить следующие импорты:

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