Selenium: Как загрузить невидимые элементы из выпадающего меню (Python) - PullRequest
1 голос
/ 31 марта 2020

Я недавно практиковал свои навыки работы с Интернетом и наткнулся на эту фантастическую работу c Фабио Невеса: Если вы любите путешествовать, позвольте Python помочь вам очистить лучшие дешевые полеты!

Вместо того, чтобы очищать сайт «Каяк», такой как Фабио, я решил попробовать и создать бота, который очистил бы сайт Ryanair .

Мой подход:

Я принимаю пользовательские данные для их «аэропорта вылета». Затем я выбираю текстовое поле «От», в котором отображается раскрывающийся список. Этот раскрывающийся список содержит 234 местоположения.

Ryanair Filter Options

city_from = input('From which city? ') #Takes users input

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

elements_list = driver.find_elements_by_xpath('//div [@class="core-list-ref"]') ##Finds all Elements/Cities in the dropdown list

list_pos = [value for value in elements_list].index(str(city_from)) #Finds the value(city name) for each element in the dropdown list and tries to locate the position of the inputed 'airport of departure' in the list.

elements_list[list_pos].click() #I then try to select this option.

Однако ...

Кажется, что не все 234 города появляются, когда я использую следующий код:

driver.find_elements_by_xpath('//div [@class="core-list-ref"]')

Только первые 79 появляются Ольборг- Генуя, другие города кажутся «скрытыми». Я обнаружил, что когда я вручную прокручиваю вниз до выпадающего списка и пытаюсь повторно запустить код, он появляется. Поэтому я попытался реализовать .move_to_element(element), чтобы бот прокрутился до последнего аэропорта в выпадающем списке. Но это все еще только позволяет прокрутить до 79-го аэропорта (Генуя). Это делает мой бот sh, когда пользователь вводит такие аэропорты, как «Цюрих».

Это моя первая попытка очистки. Как я могу преодолеть эту проблему, или есть лучший способ выбрать «аэропорт вылета». Пожалуйста, дайте мне знать, если вам нужно больше деталей.

Ответы [ 2 ]

1 голос
/ 31 марта 2020

Если вы прокрутите весь список вниз из списка «От», вы увидите, что у вас есть 256 элементов, соответствующих xpath, который вы упомянули в вопросе //div [@class="core-list-ref"], и только 253 из них являются уникальными аэропортами (внимательно посмотрите на разработчика). консоль, и вы увидите, о чем я говорю). Чтобы справиться с этим и ради творчества, ниже приведен другой угол решения проблемы - получить все аэропорты из вида карты.

WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.XPATH,"//*[@icon-id='glyphs.earth']")))
driver.find_element_by_xpath("//*[@icon-id='glyphs.earth']").click() #click Map View

WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CLASS_NAME,"airports")))
airports_root=driver.find_element_by_class_name('airports')
airport_tags=airports_root.find_elements_by_tag_name('text')

airport_names=[]
for airport in airport_tags:
    airport_names.append(airport.get_property('innerHTML'))

Обратите внимание, что это названия аэропортов, не обязательно совпадающие с названиями городов, например, введите "Murcia", и оно автоматически завершится до "Murcia International".

Вы можете сравнить введенные вами данные для этого списка (избегайте == из-за примечания выше и других причин), чтобы убедиться, что он действителен, и введите его в поля From / To. Обратите внимание, что приведенный ниже код не включает проверку данных:

#From
valid_city_from = input('From which city? ')
departure=driver.find_element_by_xpath("//div[@name='departureInput']//div[@class='disabled-wrap']/input")
driver.execute_script("arguments[0].value = '"+ valid_city_from + "';", departure)

# To
valid_city_to = input('To which city? ')
destination=driver.find_element_by_xpath("//div[@name='destinationInput']//div[@class='disabled-wrap']/input")
driver.execute_script("arguments[0].value = '"+ valid_city_to + "';", destination)

Кстати, эти импорты необходимы для WebdriverWait:

from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
1 голос
/ 31 марта 2020

пожалуйста, найдите ниже решение:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.action_chains import ActionChains


driver = webdriver.Chrome(executable_path=r"C:\New folder\chromedriver.exe")
driver.maximize_window()
wait = WebDriverWait(driver, 20)
driver.get("https://www.ryanair.com/ie/en/cheap-flights/?from=DUB&out-from-date=2020-03-31&out-to-date=2021-03-31&budget=150")
inputBox = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@name='departureInput']//div[@class='disabled-overlay']")))

actionChains = ActionChains(driver)
actionChains.move_to_element(inputBox).click().perform()

list = wait.until(EC.presence_of_all_elements_located((By.XPATH, "//div[@class='core-list']")))

for element in list:
     print element.text

Выход:

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...