Python Selenium Выбрать из выпадающего меню поиска (не работает)
Я пытаюсь освоить селен, поэтому выбрал этот сайт в качестве стартера, думал, что на нем всего понемногу, но немного застрял.
"https://www.mastercard.co.uk/en-gb/personal/get-support/convert-currency.html"
и я пытаюсь зациклить и получить разные конвертации валюты.
Для начала я просто ищу фунты стерлингов и доллары США с суммой = 1 и 0 комиссией банка.
Я могу выбрать почти все, кроме id = "cardCurr", которые у меня не работают.
Я могу выбрать первое раскрывающееся меню для GBP, но использование того же кода для второго раскрывающегося списка не работает, что заставляет меня думать, что код для первого раскрывающегося списка - это что-то вроде кладжа:?
любая помощь / направление приветствуются
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import time
options = webdriver.ChromeOptions()
options.add_argument("--window-size=1920x1080")
options.add_argument('--ignore-certificate-errors')
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
options.binary_location = r'"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
driver = webdriver.Chrome(executable_path=r'C:\cygwin64\home\#####\chromedriver.exe')
driver.implicitly_wait(10)
driver.get("https://www.mastercard.co.uk/en-gb/personal/get-support/convert-currency.html")
driver.implicitly_wait(60)
# -- accept cookies
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@id='onetrust-accept-btn-handler' and normalize-space()='Accept cookies']"))).click()
# -- end accept cookies
# -- transaction currency - GBP
WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, "//button[@id='tCurrency' ]"))).click()
textbox3 = WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, ".//*[@name='transactionCurr']")))
textbox3.send_keys('GBP')
WebDriverWait(driver,3).until(EC.element_to_be_clickable( (By.XPATH, ".//*[@class='ng-binding']"))).click()
# -- end transaction currency
# -- currency amount == 1.0
textbox = driver.find_element_by_xpath(".//*[@id='txtTAmt']")
textbox.send_keys('1.0')
# -- end currency amount
# -- card currency - USD
WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, "//button[@id='cardCurrency' ]"))).click()
textbox4 = WebDriverWait(driver, 3).until(EC.element_to_be_clickable((By.XPATH, ".//*[@name='cardCurr']")))
textbox4.send_keys('USD')
WebDriverWait(driver,3).until(EC.element_to_be_clickable( (By.XPATH, ".//*[@class='ng-binding']"))).click()
# -- end card currency
# -- bank fee - 0
textbox2 = driver.find_element_by_xpath(".//*[@id='BankFee']")
textbox2.send_keys('0')
textbox2.send_keys('RETURN')
# -- end bank fee
## driver.close()
1 ответ
Ваша проблема заключается в «щелчке», который вам не подходит.
Это происходит потому, что в обоих полях вы использовали:
wait...(By.XPATH, ".//*[@class='ng-binding']")).click()
Локатор
class='ng-binding'
не является уникальным, и после проверки вы увидите, что в момент первого щелчка, который вы выполнили, первый элемент, запрошенный таким образом, действительно является тем элементом, который вы хотели.
Но во второй раз, когда вы выполнили щелчок, вы все равно щелкнули тот же элемент («GBP»), потому что селен обычно занимает 1-й элемент, когда есть несколько совпадений для локатора.
Чтобы исправить это, вы должны изменить свой локатор на что-то, что представляет искомый элемент, например текст:
"//*[@id = 'tcurrency']/following-sibling::div[contains(@class, 'dropdown-block')]//*[contains(text(), 'GBP')]"
//*[@id = 'tcurrency']
: Ищет обертку части "Валюта транзакции", затем
following-sibling::div[contains(@class, 'dropdown-block')]
: Мне нужен div, который является первым следующим родственником элемента из предыдущей части, я не использую индекс, поскольку он не так стабилен, как обращение к классу dropdown-block, который, конечно, представляет собой раскрывающийся список.
//*[contains(text(), 'GBP')]
: Наконец, я хочу найти элемент, соответствующий моей валюте, которую я ищу, поэтому я буду искать элемент, содержащий текст «GBP».
Дополнительные примечания, не относящиеся к решению:
Вы не должны смешивать неявное ожидание с явным ожиданием, обратитесь к этому: https://itnext.io/how-to-using-implicit-and-explicit-waits-in-selenium-d1ba53de5e15
Кроме того, поскольку все ваши явные ожидания имеют одинаковую продолжительность, вам следует просто создать один объект в начале кода и повторно использовать его всякий раз, когда вам нужно, это улучшит ваш код.
И, наконец, вы можете использовать другие локаторы, отличные от XPath, такие как ID, Classname и другие, что упростит чтение кода.