硒改变后如何获取元素?

How to get an element after it has changed in selenium?

我有一些广告页面在点击某个项目后会显示 phone 数字,但所有这些页面都可以有不同的格式,并且会在很长一段时间内对它们进行迭代。 Page example.

我尝试在页面上找到一个可点击的元素,保存它和父元素,点击元素然后通过父元素找到,但是我做不到:

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

>>>                                                                                                                                                                                              

最有可能的是,点击某个元素后整个页面都会发生变化。我能做什么?

要提取 phone 数字,您需要先 scrollIntoView 元素,然后为 element_to_be_clickable() 引入 WebDriverWait,您可以使用以下 :

  • 代码块:

    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
    

点击phone后,可以使用下面的xpath得到innerHTML:

//div[@id="job-description"]//p//b[contains(.,"+")]//ancestor::p

使用.find_elements*并迭代提取它们:

ActionChains(driver).move_to_element(phone).perform()
time.sleep(1)
phone.click()
time.sleep(1)
elements = driver.find_elements_by_xpath('//div[@id="job-description"]//p//b[contains(.,"+")]//ancestor::p')

for element in elements:
    print(element.get_attribute('innerHTML'))