Python Selenium how to find element with changing text - python

I am working on a program that auto-completes questions. But the answers to the questions are choices and they will change every time.
There are four choices and I only want it to click one of them.
This work but the text will change every time: driver.find_element_by_xpath("//p[contains(text(),'The home of a person/ company.')]").click()
I have tried this: driver.find_element_by_class_name("choices").click() and it won't work.
So, I want no matter what the text part is, the program can search and click on it. But only clicking one of the choices.
Picture of the website with html
HTML:<p class="choices" xpath="1">The home of a person/ company.</p>
xpath of this://p[contains(text(),'The home of a person/ company.')]
absXpath:/html[1]/body[1]/div[2]/div[1]/div[2]/div[1]/div[2]/div[1]/div[1]/div[2]/div[1]/div[2]/div[1]/div[3]/div[1]/div[3]/div[1]/label[4]/p[1]
Please help.

first check wheather you are using correct xpath because the xpath changes as the position of options are changed. Also, according to your code you can use specific id for this problem because class can be provieded for multiple elements but id is unique.

To click the first option use css selector:
driver.find_element_by_css_selector(".tbtow.exercise_frame>.each_question.mc_question>label:nth-child(1)>p")
Check classes spelling by yourself because I typed them from the picture you provided. Also, experiment with :nth-of-type(1) instead of :nth-child(1)
To change position use :nth-of-type(2), :nth-of-type(3) and so on.

Related

Selenium Python Help Getting element of a form

Iv been trying to get the form elements on this website and for some reason I cant get them. Iv tried every way I can think of. I would really appreciate some help.
Here is my latest attempt
inputs = driver.find_elements_by_xpath("//input[#type='text']")
Here is the website.
Thanks in advance.
Edit : Github link for project
Edit : Ok so I found out that if you go straigt to website that the btn points to then it works. So I am assuming that slenium does not automaticly update to the HTML of the current page. How does one do this?
if you are getting 'NoSuchElementException', try using conditional wait before you do find_element. When you are loading another page wait until the element is visible and can be interacted.
Guide for that is here
check if the element is inside in iform, if so use
driver.switchTo().frame("framename")
EDIT
Focus on something unique in the tag. For your example use the class name used in the div. Do not use the ID tag identifier as it changes over time.
//*[contains(#class, 'ginput_container ginput_container_text')]/following::*[contains(text(),'Email')]/following::div[1]/descendant::input

Find element by value Selenium/Python

I am using Selenium with Python to automaticlly extract some data from our power plants and right now I need to click on an element.
The problem is that the element's xpaths and order change for each plant we are monitoring. The only static info is the value, just like in the 3rd line value="T_U0.
I tried many approaches and I couldn't find a solution. I can't use index or child because the order of the parameters is changing. I tried CSS selector with no success.
Here you get some of my tries...
driver.find_element_by_xpath("//input[#value='T_U0']").click()
driver.find_element_by_css_selector("input[#data-id-sys-abbreviation='388']").click()
I tried many other things but I was just desperately trying anything.
What I really need is a find_by_value, if there is a way of doing it please let me know, if there isn't please show me how I can do it.
I need to click in some options that change order accordingly to the plant
The problem is with the first xpath. You are trying to locate an input while you need to get option.
Try this:
driver.find_element_by_xpath("//option[#value='T_U0']").click()
You can try to click/select element via displayed text.
Pseudo code:
driver.find_element_by_xpath("//option[text()="Some text"]").click()

Finding locator by text?

I would like to know if there is a way to get locator for any text in robot framework ? I am using Robot Framework with Selenium2Library.
Scenario example : Suppose I have message "Hello" on my page and its position keeps on changing when new message appears.I want to click on this "Hello" word to show complete message. How can I do that. Please help.
I've seen locations change a lot with Angular webpages, so I understand what you mean. IDs can be generated anew every time the page loads and may change depending on the order in which you click on elements. Worse, they can affect dom- and xpath-based locators as well. The short answer to your question is no, it doesn't exist within standard Selenium, Selenium2, ExtendedSelenium2, or any other standard library.
The medium answer to your question is solved in my currently-most-advanced Click Element by Text custom keyword. It generates an xpath based on your inputs and if it can be found with a simple text search with no extra parameters, it'll do it. It is testy at times and may require argument injections to work, but in general it works very well and is easy to use when xpaths are remotely possible.
Click Element by Text
# EXAMPLE USAGE
# Click Element by Text "text on the element" id="midlevellocationoftext" button
# NOTE: Does not account for extra spaces at the beginning or end, text must be exact
# NOTE: Allows for injections on purpose to allow user to be more exact with their location
[Arguments] ${text} ${location}=* ${elementtype}=*
Click Element xpath=//*[#${location}]//${elementtype}[text()=${text}]
The long answer is that I'm working on something better. Here's what I know so far. The elements to do this do exist out there in the void. JavaScript can turn a webpage into a list of elements. I can call .innerHTML on those elements to get their text. I haven't worked out the details, but I honestly think it's possible and when I get it figured out, the code will be on Code Review for others to see.

Selenium (python) switching to popup panel

I am trying to use Selenium with Python to click on a text field, which opens a pop-up panel, select the text entry area of that popup, and enter text to it.
switch_to_window and switch_to_frame don't seem to be working. In a previous question I asked about Selenium, someone told me to pause the program until the element I need is available. The solution worked for that problem, but not this one, so I'm assuming I have a different issue and I'm too new to Selenium to understand what it is.
This is what the original box I'm trying to click on looks like:
And the Inspect Element for this box:
When that description box is clicked, it should open this window:
And select this element to enter text into:
So in my code I have:
descriptionBox = driver.find_element_by_id('kiadvany_fulszoveg_text')
descriptionBox.click()
That does not error the program, but it also doesn't seem to actually be clicking on that element. To make matters more confusing, I got this to work exactly ONCE, where it opened the correct Description text box as pictured above, but it has since not worked at all even when I try the exact same thing.
The panel's ID is:
As I mentioned, switching to this panel ID using switch_to_frame or switch_to_window was the first thing I tried, but I'm getting a No Such Element error.
Because I saw the description box open correctly once, but never again, I'm assuming that's where the problem is. I wish, the one time it did pop up, that I'd tried to put the text into the field to see if that would work too, but I hadn't gotten there yet at that point, so I don't know if that would have worked.
Thank you in advance to anyone who can help with this!
Try this
descriptionBox = driver.find_element_by_id('kiadvany_fulszoveg_text')
driver.execute_script('arguments[0].click();', descriptionBox)
or
actions = ActionChains(driver)
actions.move_to_element(descriptionBox)
actions.click(descriptionBox)
actions.perform()

Python with Selenium - Cannot find and click this specific element due to randomization of it's location on the site

I've been creating a tool that plays through an online game using python 2.7 and selenium, and am very stuck on one particular element I need to select.
The UI looks as follows:
1 2 3
a d g
b e h
c f i
The numbers one two and three represent a drop down menu, which when clicked open up the letters. Each option represents a different outcome. The problem is, at the start of each game the positions of both the numbers and letters are randomized. In the code, each button's css selector is labeled as for example "#action-1 > button:nth-child(1)", as in the "first button", but the "first button" will be different every game.
I've tried finding by link text, xpath, and css selector to no success.
If it helps, pressing "copy outer html" gives this:
<button class="ng-binding" ng-click="subBtn($event)" ng-class="{disabled : !state.chapterStart || state.btns.indexOf(btn.action) != -1}" ng-disabled="!state.chapterStart || state.btns.indexOf(btn.action) != -1">Wait and See What They Do</button>
The "Wait and See What They Do" part of it is what the button says and is how you know what to click, but I can't seem to find the element by that.
Copying the xpath results in //*[#id="action-1"]/button, which again isn't really helpful because telling it to click that would just be like saying "click the button that is in the first position", and it changes every time. I've added long time.sleep() commands to test, the page is definitely loading all the way so that is not the issue.
Anyways, I've been trying to figure this one out for way too long and it has me stumped. I'd be very grateful for any input you all can give. Thank you!
If you are looking to locate an element by the text it contains you can use XPath. You stated that you tried XPath but no specifics were given. Did you try the below? It should work given the HTML you provided.
//button[text()='Wait and See What They Do']
To read this XPath... find any descendant // that is a BUTTON tag that has an attribute [] where the text contained in the element is equal to the search string, text()=''.
Another example might be the below which is an alternate way to find your button. The problem with this way is that there may be many buttons on the page with that class so it may not be specific enough.
//button[#class='ng-binding']
I've found (and others have also) that XPaths are generally slower than other location methods. Because of this, I generally prefer By.Id, when available, then By.CssSelector. They are both significantly faster than XPath. I save XPath for things like finding text in an element or finding relative elements (CSS can do this some but is no where near as powerful as XPath).
XPath Examples

Categories

Resources