Как нажимать на определенные даты с календарем, используя Selenium и Python - PullRequest
0 голосов
/ 11 января 2019

Я пытаюсь прочитать данные с веб-сайта, который содержит несколько раскрывающихся меню и таблиц с использованием Selenium. Вот ссылка: "https://markets.ft.com/data/funds/tearsheet/historical?s=NL0006294175:EUR".

Мне нужно изменить диапазон дат, предположим, что я хочу увидеть цены на эту акцию с 1 января по 5 января, поэтому я нажимаю на 2 маленьких календаря. Выбор и нажатие на определенную дату из таблицы слева - это нормально, мне удается без проблем использовать селекторы xpaths и css.

Однако щелкнуть дату в таблице справа очень сложно, и я не понимаю, почему. Python всегда отображает ошибки, такие как:

selenium.common.exceptions.ElementNotVisibleException: Message: element not interactable

Вот мой код:

driver.get(r'https://markets.ft.com/data/etfs/tearsheet/historical?s=O9P:SES:USD')
driver.find_element_by_css_selector("body > div.o-grid-container.mod-container > div:nth-child(2) > section.mod-main-content > div:nth-child(1) > div > h2 > span").click()
driver.find_element_by_css_selector("body > div.o-grid-container.mod-container > div:nth-child(2) > section.mod-main-content > div:nth-child(1) > div > div > div.mod-ui-filter-overlay.clearfix.mod-filter-ui-historical-prices-overlay > div.mod-ui-overlay.mod-ui-filter-overlay__form > div > form > fieldset > span > div.mod-ui-date-picker.mod-filter-ui-historical-prices-overlay__date--from > div.mod-ui-date-picker__input-container > i").click()
driver.find_element_by_xpath('//*[@title="Next month"]').click()
driver.find_element_by_xpath("//*[@aria-label='1 Jan, %d']" %(y)).click()  #The click on the table on the left works
driver.find_element_by_css_selector("body > div.o-grid-container.mod-container > div:nth-child(2) > section.mod-main-content > div:nth-child(1) > div > div > div.mod-ui-filter-overlay.clearfix.mod-filter-ui-historical-prices-overlay > div.mod-ui-overlay.mod-ui-filter-overlay__form > div > form > fieldset > span > div.mod-ui-date-picker.mod-filter-ui-historical-prices-overlay__date--to > div.mod-ui-date-picker__input-container > i").click() 
time.sleep(2)
driver.find_element_by_xpath("//*[@aria-label='5 Jan, %d']" %(y)).click()   #this does not work, the element is not interactable

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

Знаете ли вы, есть ли способ нажать на дату во второй таблице?

Заранее спасибо.

Ответы [ 4 ]

0 голосов
/ 11 января 2019

Вы можете попробовать код ниже для событий календаря.

driver.findElement(By.xpath("//div[contains(@class, 'date--from')]")).click();
driver.findElement(By.xpath("//div[contains(@class, 'date--from')]//div[contains(@class,'picker__nav--next')]")).click();
driver.findElement(By.xpath("//div[contains(@class, 'date--from')]//div[@aria-label='1 Jan, 2019']")).click();
driver.findElement(By.xpath("//div[contains(@class, 'date--to')]")).click();
driver.findElement(By.xpath("//div[contains(@class, 'date--to')]//div[contains(@class,'picker__nav--next')]")).click();
driver.findElement(By.xpath("//div[contains(@class, 'date--to')]//div[@aria-label='5 Jan, 2019']")).click();

Если это не сработает, вы можете использовать некоторое время ожидания после нажатия на календарь, чтобы открыть календарь.

0 голосов
/ 11 января 2019

Есть 2 проблемы, когда вы нажимаете первую дату, там будет перекрывающийся элемент, который мешает щелкнуть по второму входу, вам нужно подождать, пока этот элемент не будет удален, вам нужно выбрать вторую дату ввода, это можно сделать с помощью xpath (//the_xpath_selector)[2]

driver.get(r'https://markets......')
driver.find_element_by_css_selector('h2 span[data-mod-action="toggle-filter"]').click()
# 4 input, index 1 and 3 are hidden
inputDate = driver.find_elements_by_css_selector('.mod-ui-date-picker input')
inputDate[0].click()
driver.find_element_by_xpath('//*[@title="Next month"]').click()
driver.find_element_by_xpath("//*[@aria-label='1 Jan, %d']" %(y)).click() 
# wait until the element removed
wait.until(
    lambda d: len(d.find_elements_by_css_selector('.mod-ui-loading__overlay')) == 0
)
inputDate[2].click()
# select second date piker "[2]"
driver.find_element_by_xpath("(//*[@aria-label='5 Jan, %d'])[2]" %(y)).click()
0 голосов
/ 11 января 2019

Чтобы увидеть цены этой акции с 1 января до 5 января перед кликом, вам нужно вызвать WebDriverWait для желаемого элемента , который будет кликабельно , и вы можете использовать следующее решение:

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

    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    
    options = webdriver.ChromeOptions()
    options.add_argument("start-maximized")
    options.add_argument("disable-infobars")
    options.add_argument("--disable-extensions")
    driver= webdriver.Chrome(chrome_options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
    driver.get(r'https://markets.ft.com/data/etfs/tearsheet/historical?s=O9P:SES:USD')
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[@class='mod-ui-filter-overlay__filter-toggle']"))).click()
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='mod-ui-date-picker mod-filter-ui-historical-prices-overlay__date--from']//i[@class='mod-icon mod-icon--calendar']"))).click()
    driver.find_element_by_xpath("//div[@class='mod-ui-date-picker mod-filter-ui-historical-prices-overlay__date--from']//div[@title='Next month']").click()
    driver.find_element_by_xpath("//div[@class='mod-ui-date-picker mod-filter-ui-historical-prices-overlay__date--from']//div[@aria-label='1 Jan, 2019']").click()
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//div[@class='mod-ui-date-picker mod-filter-ui-historical-prices-overlay__date--to']//i[@class='mod-icon mod-icon--calendar']"))).click()
    driver.find_element_by_xpath("//div[@class='mod-ui-date-picker mod-filter-ui-historical-prices-overlay__date--to']//div[@aria-label='5 Jan, 2019']").click()
    
  • Снимок браузера:

Calander_Clicks

0 голосов
/ 11 января 2019

Проблема в том, что есть 2 элемента, которые соответствуют селектору, который вы упомянули на этой странице. Самый простой способ проверить это - открыть консоль браузера и вручную просмотреть ваш случай.

Вам нужен способ различать два. Чтобы получить четкий путь к xpath, у вас должен быть одновременно открыт только один из сборщиков дат. Тогда вы можете использовать что-то вроде следующего, чтобы получить совпадение.

//div[contains(@class,'picker--opened')]//*[@aria-label='5 Jan, 2019']
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...