Select Date from dropdown datepicker using Selenium and Python - python

I tried to select different date rather than default (current date). e.g the initial page pop up with shareholding date : 2023/02/01, but I want to select different date say, 2022/12/23 from the dropdown menu.
My environment is : Selenium 4.3.0 and Python 3.9.7, Chrome
Following is my code:
url = "https://www3.hkexnews.hk/sdw/search/mutualmarket.aspx?t=hk&t=hk&t=hk&t=hk"
driver = webdriver.Chrome()
driver.get(url)
select_element = driver.find_element(By.XPATH, "//input[#name='txtShareholdingDate']").click()
# The above pop up the required page with Date dropdown, tried different code to select the date but failed. My codes are:
action = ActionChains(select_element)
action.send_keys("2023",Keys.ARROW_DOWN)
action.send_keys("1",Keys.ARROW_DOWN)
action.send_keys("31",Keys.ARROW_DOWN)
action.send_keys(Keys.ENTER)
action.perform()
# AttributeError: 'NoneType' object has no attribute 'execute'
# Also tried
select = driver.find_element(By.ID, "txtShareholdingDate")
select.select_by_value("2023/01/31")
driver.find_element(By.ID, 'btnSearch').click()
Error:
AttributeError: 'WebElement' object has no attribute 'select_by_value'
Any suggestions?

The <input> element to select a date within the website is having the attribute readonly="readonly" set:
<input name="txtShareholdingDate" type="text" value="2023/02/01" id="txtShareholdingDate" class="input-searchDate active" data-reset="2023/02/01" readonly="readonly">
Solution
To select a date you need to remove the readonly attribute and set the value attribute to the new date as follows:
driver.get("https://www3.hkexnews.hk/sdw/search/mutualmarket.aspx?t=hk&t=hk&t=hk&t=hk")
element = driver.find_element(By.CSS_SELECTOR, "input#txtShareholdingDate")
driver.execute_script("arguments[0].removeAttribute('readonly')", element)
driver.execute_script("arguments[0].setAttribute('value', '2023/01/31')", element)
driver.find_element(By.CSS_SELECTOR, "input#btnSearch").click()
Browser snapshot:

select tag is not used in the HTML DOM for this dropdown. Hence select class cannot be used in this case.
driver.find_element(By.XPATH, "//input[#name='txtShareholdingDate']").click()
After the above line, just try the following code:
driver.find_element(By.XPATH, "//button[#data-value='2022']").click()
driver.find_element(By.XPATH, "//button[#data-value='11']").click()
driver.find_element(By.XPATH, "//button[#data-value='23']").click()
driver.find_element(By.ID, "btnSearch").click()
Above 4 lines will click on dropdown values 2022, 11, 23 and then clicks on Search button

You can also use javascript to set the dat without having to set the date by using ActionChains as you have. This is also much quicker and less error prone
newDate = "2023/01/18"
dateElement = wait.until(EC.presence_of_element_located((By.XPATH,"//input[#name='txtShareholdingDate']")))
print(dateElement .get_attribute("value"))
driver.execute_script("arguments[0].setAttribute('value',arguments[1])", dateElement , newDate )

Related

How to select option in dropdown using Selenium in Python (Jupyter Notebook)

I am trying to select dropdown year of 2021 on (https://www.theknot.com/registry/couplesearch) and am unable to figure out how to use the dropdown.
#This code is working
typetextfirst = driver.find_element_by_id("couples-search-first-name")
typetextfirst.clear()
typetextfirst.send_keys(row["First"])
typetextlast = driver.find_element_by_id("couples-search-last-name")
typetextlast.clear()
typetextlast.send_keys(row["Last"])
typetextyear = driver.find_element_by_id("couples-search-year")
#None of these options work to populate the year
typetextyear.selectByIndex(1)
typetextyear.select_by_index(1)
typetextyear.selectByVisibleText("2021")
typetextyear.select_by_visible_text("2021")
#This code is working
typetextlast.send_keys(Keys.ENTER)
Page doesn't use standard dropdown widget but it uses button and ul to emulate dropdown.
This code works for me on Firefox and Chrome on Linux Mint.
First I click button to open dropdown created with ul and later I search li with expected text and click it.
Because it may have text 2021 with some spaces/tabs/enters (which browser doesn't show) so I prefer contains instead of =
from selenium import webdriver
url = 'https://www.theknot.com/registry/couplesearch'
driver = webdriver.Firefox()
#driver = webdriver.Chrome()
driver.get(url)
year_dropdown = driver.find_element_by_id("couples-search-year")
year_dropdown.click()
year = year_dropdown.find_element_by_xpath(".//li[contains(text(), '2021')]")
#year = year_dropdown.find_element_by_xpath(".//li[text()='2021']")
year.click()

How to send keys to this element

I am using Python selenium chrome driver and i am stuck at filling out the csc and the year of the creditcard information field ( look at picture ). The credit card number and month works fine with this code:
iframe = driver.find_element_by_xpath("//iframe[#class='js-iframe']")
driver.switch_to.frame(iframe)
inputCC = WebDriverWait(driver, 30).until(
lambda driver: driver.find_element_by_id("encryptedCardNumber")
)
inputCC.send_keys("1111222233334444")
driver.switch_to.default_content()
time.sleep(1)
iframe = driver.find_element_by_xpath("//iframe[#class='js-iframe']")
driver.switch_to.frame(iframe)
inputCC = WebDriverWait(driver, 30).until(
lambda driver: driver.find_element_by_id("encryptedExpiryMonth")
)
inputCC.send_keys("08")
driver.switch_to.default_content()
I tried to use the same for the csc and year with changing the id but it didnt work.
How to do it?
I don't run your code, but I checked the HTML & your code. Here's what I think:
Because //iframe[#class='js-iframe'] is a very general XPATH, you need to be more specific. In your site, you have many iframes with the same XPATH.
You can fill the Month because after calling iframe = driver.find_element_by_xpath("//iframe[#class='js-iframe']"), it gives you the FIRST iframe, which contains the Month.
Your code fails for Year/CSC because it uses the FIRST iframe (which contains Month) to locate Year & CSC.
To fix, you have 2 methods.
Write the correct XPATH.
Month iframe: //span[#data-cse="encryptedExpiryMonth"]/iframe
Year iframe: //span[#data-cse="encryptedExpiryYear"]/iframe
CSC iframe: //span[#data-cse="encryptedSecurityCode"]/iframe
Find a list of iframes
iframe_list = driver.find_elements_by_xpath("//iframe[#class='js-iframe']")
month_iframe = iframe_list[0]
year_iframe = iframe_list[1]
csc_iframe = iframe_list[2]

Selenium calendar picker: I can click manually but Selenium cant click

I am attempting to choose date on a calendar on this website. On the first calendar (date from) I can choose the desired date using Selenium, however, I get the following error while clicking on the desired month even though the exact element is found.
ElementNotInteractableException:element not interactable
To me, it seems weird because I can click on the month manually.
Here is what I have tried so far
from selenium import webdriver
import time
year = 2019
month = 'JAN'
driver_path = 'pathtochromedriver\chromedriver.exe'
url = 'https://app.cpcbccr.com/ccr/#/caaqm-dashboard-all/caaqm-landing/data'
driver = webdriver.Chrome(driver_path)
driver.get(url)
time.sleep(8)
# find desired calendar
to_date = driver.find_element_by_xpath('//*[#id="date2"]/angular2-date-picker/div/div[1]/i')
to_date.click()
# Click on year dropdown
to_year = driver.find_element_by_xpath('//*[#id="date2"]/angular2-date-picker/div/div[2]/div[3]/div')
to_year.click()
driver.find_element_by_xpath('//*[#id="{}"]'.format(year)).click()
# Click on month dropdown
to_month = driver.find_element_by_xpath('//*[#id="date2"]/angular2-date-picker/div/div[2]/div[2]/div')
to_month.click()
mm = driver.find_element_by_xpath('//*[#id="{}"]'.format(month))
mm.click()
Mistake in code mm = driver.find_element_by_xpath('//*[#id="{}"]'.format(month)). You find first element in DOM(which combined with element data instead data2) and it is not visible yet.
There is workig code
mm = driver.find_element_by_id('date2').find_element_by_class_name('months-view').find_element_by_id(month)
mm.click()
Also good deal, to use WebDriverWait, because the site is very slow.
for example
to_date = WebDriverWait(driver, 10).until(
expected_conditions.presence_of_element_located(
(By.XPATH, '//*[#id="date2"]/angular2-date-picker/div/div[1]/i')))

How to select dropDown options when is not with <Select> tag with Selenium in Python

Would like to select the date in the following URL (Yellow highlighted):
https://www.hkex.com.hk/mutual-market/stock-connect/statistics/historical-daily?sc_lang=en-hk#select4=3&select5=1&select3=0&select1=1&select2=6
And when inspecting the HTML code, I couldn't find any "select" tag as below:
My code:
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument("window-size=1920,1080")
driver=webdriver.Chrome(options=chrome_options, executable_path=r'/Users/Woodylin/Desktop/Python Learnings/chromedriver')
#driver=webdriver.Chrome(options=chrome_options, executable_path=r'C:/Users/wolin/Desktop/Python/chromedriver.exe')
url1 = 'https://www.hkex.com.hk/Mutual-Market/Stock-Connect/Statistics/Historical-Daily?sc_lang=zh-HK#select4=2&select5=1&select3=0&select1=1&select2=6' #滬港通
driver.get(url1)
sleep(3)
ele_date = driver.find_element_by_id('select-target-date') #Target Date
DropDown1 = Select(ele_date)
DropDown1.select_by_visible_text('7')
So how could I set the select the option?
Current Update:
Found that if I use the following XPATH will select "5th" day
driver.find_element_by_xpath("//*[#id='mainform']/div[8]/main/section/div[2]/div[1]/div[2]/div[**5**]/a").click()
#However, if I use the command below to select "31st" day, it returns below error:
Err msg: selenium.common.exceptions.ElementNotInteractableException: Message: element not interactable
driver.find_element_by_xpath("//*[#id='mainform']/div[8]/main/section/div[2]/div[1]/div[2]/div[**31**]/a").click()
Select Docs:
Constructor. A check is made that the given element is, indeed, a SELECT tag.......
Your target element isn't SELECT tag. So you can't use Select
Try another approach with css selector. You need click first the date element to make dropdown bring up the date list, and before click element target, use location_once_scrolled_into_view first.
driver.find_element_by_css_selector('div.csm-dailystat-day-selection').click()
target_date = '7'
ele_date = driver.find_element_by_css_selector('div.csm-dailystat-day-selection div[data-value="{}"]'.format(target_date))
ele_date.location_once_scrolled_into_view
ele_date.click()

Webscrape table from CME, including selection of desired table from drop down menu

The below code works. It returns data in the default loaded table (making use of answer provided here: link, but how to access the other tables (that can be found by clicking on the 'Contracts' button and selecting from the menu a different contract, eg. Mar 2019)?
driver.get("http://www.cmegroup.com/tools-information/quikstrike/treasury-analytics.html")
# Need to include some more time here for data in iframe to load?
driver.implicitly_wait(3)
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
soup = BeautifulSoup(driver.page_source, 'html.parser')
CMEtreasuryAnalytics._table = soup.select('table.grid')[0]
I tried this but get the following error returned: NoSuchFrameException: Message: no such frame: element is not a frame
driver.get("http://www.cmegroup.com/tools-nformation/quikstrike/treasury-analytics.html")
cDate = 'Dec 2018'
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
elements = driver.find_elements_by_class_name("square-corners ")
options = [element.get_attribute("innerText") for element in elements]
if cDate in options:
element = elements[options.index(cDate)]
else:
pass
driver.switch_to.frame(element)
I've also tryed to 'click()' but couldn't get that to work either. I'm new to selenium and would appreciate some pointers on how to access the said data. I'm using python and chrome webdriver.
OK. I think I worked it out. The menu lies within the iFrame,
so after getting the element details, then need to click() the menu, then element.click(), then scrape the displayed data. The final code follows, but I don't know if it's the most straightforward way to approach it.
driver.get("http://www.cmegroup.com/tools-nformation/quikstrike/treasury-analytics.html")
cDate = 'Jun 2019'
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
elements = driver.find_elements_by_class_name("square-corners ")
options = [element.get_attribute("innerText") for element in elements]
if cDate in options:
element = elements[options.index(cDate)]
else:
pass
# Click the dropdown menu labelled 'Contracts'
driver.find_element_by_xpath('//*[#id="ctl00_MainContent_ucViewControl_IntegratedStrikeAsYield_ucContractPicker_ucTrigger_lnkTrigger"]').click()
driver.implicitly_wait(1)
element.click()
driver.switch_to.frame(driver.find_element_by_tag_name("iframe"))
soup = BeautifulSoup(driver.page_source, 'html.parser')
CMEtreasuryAnalytics._table = soup.select('table.grid')[0]
Update:
The above worked for a while but then started failing with the below message. So maybe this is the right track but I need better way to select an option from the drop down list labelled 'Contracts'. How to do that?
Message: unknown error: Element is not clickable at point (511, 475). Other element would receive the click: <

Categories

Resources