interact elements with dynamic label in python selenium - python

Python newbie here. All of 1 month old. Most of the elements in page i am trying to scrape, i am able to handle them and interact with them. there are two elements that have dynamic labels which i am not able to handle. The source page looks as below
<span class="a-button-inner">
<input class="a-button-input" type="submit" aria-labelledby="Ae8MCi-55">
<span id="Ae8MCi-55" class="a-button-text" aria-hidden="true">Add Your Key</span>
</span>
Upon each refresh the label is new so i cannot get a fixed XPATH of that. There are multiple items with span class "a-button-inner" as well as input class "a-button-input" and there are other submit buttons as well in the rest of the page. The only thing unique is the Span text "Add Your Key".
Appreciate all help to get the submit button element and to click/submit it.
from selenium import webdriver
.
.
.
.
# objAddKey = driver.find_element_by_xpath('//*[#id="Ae8MCi-55"]/span/input') does not work as second round its a different XPath
objAddKey = driver.find_element_by_link_text('Add Your Key') # hoping this will get a sibling and then to get the parent and then look for all the children. I don't even know if its possible in python.
objAddKey.click()'
Tried to search for searching by span text, and came across some other stuff,
https://www.tutorialspoint.com/how-to-get-text-found-between-span-selenium
WebElement l = driver.findElement(By.xpath("//p/span"));
String s = l.getText();
but this does not help either.
https://selenium-python.readthedocs.io/locating-elements.html
went through this, but not much help either.
Appreciate your help and pointers.
Thank you.

If Add Your Key is unique then you can use the below xpath :
//span[contains(text(), 'Add Your Key')]//preceding-sibling::input[#class='a-button-input']
or even without class :
//span[contains(text(), 'Add Your Key')]//preceding-sibling::input
and use it like this :
objAddKey = driver.find_element_by_xpath("//span[contains(text(), 'Add Your Key')]//preceding-sibling::input")
objAddKey.click()
I would suggest you to have explicit waits for more reliability.
Selenium - Python - Explicit waits

Related

Is using dynamic value on XPATH selenium possible?

I want to click some element (date) in date picker popup using selenium python, if I define the text it can be clicked. but, when I change it with formatting it not worked and I don't know why.
I already tried this way with formatting string in python way:
chosen_date = str(day_date-7)
date_choose = driver.find_element(By.XPATH, "// div[contains(text(), '{}')]".format(chosen_date))
HTML:
<div class="shopee-react-date-picker__table-cell-wrap">
<div class="shopee-react-date-picker__table-cell selected">6
</div>
</div>
but, it never worked and always throw an error and stop the script automatically. I'm quite new in using selenium to automate website, is there any possibilities to overcome this error?
Thank you so much in advance.
as I can see is there is a space in // div section of your selector. There should be not any space:
//div[contains(text()
the rest is ok.

Tagging an HTML element in Python not working

I have a script going using Selenium and on a new window pop up I am trying to retrieve this element:
<div class="custom-control p-2">somenumber</div>
The full path to this class is
html/body.modal-open/div#modalUserPRMLead.modal.fade.show/div.modal-dialog/div.modal-content/div.modal-body/div.row.justify-content-center.p-3/div.col-md-12/div.custom-control.p-2
I have tried variants of these to grab just the text of 'somenumber'
driver.find_element(By.CSS_SELECTOR,'row justify-content-center p-3').get_attribute('innerHTML')
driver.find_element(By.XPATH("html/body.modal-open/div.col-md-12./div.custom-control.p-2")).text
driver.find_element(By.XPATH("custom-control p-2")).text
driver.find_element(By.XPATH("div.row.justify-content-center.p-3")).text
driver.find_element(By.XPATH,custom-control p-2).text
driver.find_element(By.XPATH,div.custom-control.p-2).text
The errors I get is that it cannot locate the tag from current session. It's a new window that pops up as a result of previous script, I did driver.current_url just to make sure it was capturing the link to the new window in current session and it was.
I'm not understanding how to index down to the div class and just grab the text. Any help would be greatly appreciated. The script prior to window pop for form input was much easier because I could tag everything using By.NAME or By.ID
Your CSS selector is wrong. XPaths don't really looks like XPaths...
Try
driver.find_element(By.XPATH, '//div[#class="custom-control p-2"]').text
or
driver.find_element(By.CLASS_NAME, 'custom-control').text
In case element is dynamic you might need to apply wait
You can also check basic syntax of XPath and CSS-selector

Trying to click entry buttons on gleam using selenium but am having trouble identifying the element

Here is the inspect result for the button that says +5 per day
>span class="text user-links entry-method-title ng-scope ng-binding" ng-include="::'views/entry-text/'+entry_method.entry_type+'.html'">
Click For a Daily Bonus Entry"
</span>
<div class="entry-method bonus template" data-remove-popovers="" id="em6129519" ng-class="{expanded: entryState.expanded == entry_method, template: entry_method.template, 'completed-entry-method': !canEnter(entry_method) && isEntered(entry_method)}" ng-repeat="entry_method in ::entry_methods">
here is the HTML given information when I inspect the link/button, I have tried to use XPath, CSS, link text, and class name and it keeps giving me an error saying it cannot identify the element. Does anyone have a suggestion for how to identify this, it is on gleam.io for a giveaway I'm trying to automate this so i don't have to log in and press this everyday. This is my first ever web interfacing project with python.
Here is my most recent try
driver.maximize_window()
time.sleep(10)
driver.execute_script("window.scrollTo(0, 1440)")
time.sleep(10)
button2 = driver.find_element_by_class_name("text user-links entry-method-title ng-scope ng-binding")
button2.click()
Similar to a previous issue, Selenium find_element_by_class_name and find_element_by_css_selector not working, you can't have spaces in your class name when using driver.find_element_by_class_name. Instead, find the element via css_selector and replace each space with a dot.
driver.find_element_by_css_selector("span.text.user-links.entry-method-title.ng-scope.ng-binding")
That'll fix what you have above, but keep in mind there are other ways to make selenium actions more reliable (eg. WebDriverWait, etc). And there may be a cleaner selector to use than the one above.
I believe the element you want to access is contained within an "iframe", thus you must first switch to iframe before you can access it using selectors.
driver.switch_to.frame(x.find_element_by_xpath("PUT IFRAME XPATH HERE"))

Having trouble finding an element using Selenium/Python

I just want to say that I am new to Python/Selenium and I've been googling and wracking my head for hours now.
I am trying to extract a value from an element from the website we use for creating tickets at work. The thing is, the element with the ticket number has no ID and I cannot seem to be able to single it out using its other attributes.
The HTML for the elements is as follows:
<span class = "custom-field__value ng-binding ng-scope"
ng -
if = "!$parent.editMode && data.value" tooltip = ""
ng - bind - html = "((status.isCollapsed) ? (data.value | securelinky : '_blank')) || ('customField.label.noValue' | i18n)"> INC22963815
</span>
So, I want to get the INC22963815 from the element.
I tried with
ticket = driver.find_element_by_class("custom-field__value ng-binding ng-scope")
ticket = driver.find_elements_by_class("custom-field__value ng-binding ng-scope")
for number in ticket:
print(number.get_attribute("innerText"))
but I get nothing.
But when I tried with
ticket = driver.find_elements_by_tag_name("SPAN")
for number in ticket:
print(number.get_attribute("innerText"))
I found the text I am looking for, but it also outputs almost everything else on the page, so it is not very useful.
So now I am resorting to asking the question myself. I need help just to single out that one element. Thank you in advance.
Have you considered using the element's XPATH? You can use the Chropath plugin https://chrome.google.com/webstore/detail/chropath/ljngjbnaijcbncmcnjfhigebomdlkcjo, to get the element's XPath.
You can then do something like
driver.find_element_by_xpath("xpath_string_here")
Let me know if this helps!
I see you are using class name (that has spaces in it). Class name does not support spaces. so that's why it did not work. Moreover it's just a combination of multiple class separated by a space.
consider changing it to css selector :-
ticket = driver.find_element_by_css_selector("span.custom-field__value.ng-binding.ng-scope")
P.S :- it's not recommended to use automatic xpath or css generated by browser built in tools.

Selenium Find Sub-Child href Element

I'm trying to click the following link using selenium.
<div id="RECORD_2" class="search-results-item">
<a hasautosubmit="true" oncontextmenu="javascript:return IsAllowedRightClick(this);" class="smallV110" href="#;cacheurlFromRightClick=no"></a>
</div>
Which record to click is not known before the code is executed. Record_2 has multiple children, and the one included is the one I want to click. The link is edited for the sake of privacy. I tried to do something like that where name is the record variable, however it doesn't work.
driver.find_element_by_css_selector("css=div#"RECORD_%s" % (name).smallV110")
I'm a complete newbie to selenium so I couldn't figure out a way to sort this out. I would appreciate any help. Thanks!
Note that this is not Selenium IDE and you don't need the css= at the beginning of a selector.
There are multiple ways to locate the link element, e.g.:
driver.find_element_by_css_selector(".search-results-item a.smallV110")
driver.find_element_by_css_selector("[id^=RECORD] a.smallV110") # id starts with "RECORD"
If you know the id value beforehand:
id_i_know = 2
driver.find_element_by_css_selector("[id=RECORD_%d] a.smallV110" % id_i_know)
You don't have to have that smallV110 class attribute check - I've added it to increase chances of not matching other a elements inside the div (not sure what they are, you have not posted the entire HTML).

Categories