How can I interact with irregular elements using Python/Selenium? - python

I'm using a page that has out of the ordinary elements. Some of which are buttons that cannot be clicked using an xpath, link text, or id locator.
Here is the html for one button.
<div class="goog-inline-block goog-custom-button-inner-box">Save & Go Back</div>
How should I go about including these kinds of buttons and objects in my script?

You could use a CSS selector
driver.find_element_by_css_selector("div.goog-inline-block.goog-custom-button-inner-box").click()

I would say use the class, but it has a compound class name so I don't think that will work. Ask the developer to put an ID on the button.

Related

Python/Selenium: Any way to wildcard the end of an xpath? Or search for a specifically formatted piece of an xpath?

I am using python / selenium to archive some posts. They are simple text + images. As the site requires a login, I'm using selenium to access it.
The problem is, the page shows all the posts, and they are only fully readable on clicking a text labeled "read more", which brings up a popup with the full text / images.
So I'm writing a script to scroll the page, click read more, scrape the post, close it, and move on to the next one.
The problem I'm running into, is that each read more button is an identical element:
read more
If I try to loop through them using XPaths, I run into the problem of them being formatted differently as well, for example:
//*[#id="page"]/div[2]/article[10]/div[2]/ul/li/a
//*[#id="page"]/div[2]/article[14]/div[2]/p[3]/a
I tried formatting my loop to just loop through the article numbers, but of course the xpath's terminate differently. Is there a way I can add a wildcard to the back half of my xpaths? Or search just by the article numbers?
/ is used to go for direct child, use // instead to go from <article> to the <a>
//*[#id="page"]/div[2]/article//a[.="read more"]
This will give you a list of elements you can iterate. You might be able to remove the [.="read more"], but it might catch unrelated <a> tags, depends on the rest of the html structure.
You can also try looking for the read more elements directly by text
//a[.="read more"]
I recommend using CSS Selectors over XPaths. CSS Selector provide faster, cleaner and simpler way to deal with these queries.
('a[href^="javascript"]')
This will selects every element whose href attribute value begins with "javascript" which is what you are looking for...
You can learn more about Locating Elements by CSS Selectors in selenium here.
readMore = driver.find_element(By.CSS_SELECTOR, 'a[href^="javascript"]')
And about Locating Hyperlinks by Link Text
readMore_link = driver.find_elements(By.LINK_TEXT, 'javascript')

Python Selenium how to find element with changing text

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.

How to find title="xyz" element with Selenium (Python)

I am trying to click an element with Selenium, that has a specific title attribute. I have tired do use an xpath before, however, the problem is that there are two buttons on the website with the same xpath. If one button is active, it has the same xpath as the other when its active and vice versa.
The only thing that differentiates these two buttons in the title attribute.
<a class="qPKfxd" href="SOME LINK" title="List">
Basically I am trying to only click that element if the title is "List".
Has anyone got an idea of how to specify that with Selenium?
Please let me know if you need to view more code.
You can locate an element by attribute.
xpath:
//a[#title="List"]
css_selector
[title="List"]

Pythno Selenium clicking list item within ui

I am working with python and selenium to click on the Photo/Video button on a facebook page. The HTML associated with this seems to have a list item (li) inside a ui. The html is as in the following image. The button circles is the one I am trying to press.
Can anyone please tell me how should I press the Photo/Video button?
Can you try this code?
I used the xPath method and contains() to compare the text in the div.
By the way, the found object does not have the click related function, and the click function seems to be a tag among its parents
The syntax for finding a parent in xPath is /.. and I used this
https://stackoverflow.com/a/3655588/12582501
driver.find_element_by_xpath('//div[contains(text(),"Photo/Video")]/../../../a').click()
Facebook has an intresting thing: testids
With this IDs you can click all of clickable elements on the site
driver.find_element_by_xpath('//div[#data-testid="photo-video-button"]').click()
In this case you can exec your code, when on page will be another element with text "Photo/Video"

How can I click the dropdown list options?

I have a button that when I click it I will get a sort of a dropdown list. My problem is that I want to click one of the options in this dropdown list but I don't see how to refer to it.
I have tried to act as if this was a list box and I used the "Select" module but I failed with exceptions. My purpose is to be able to refer to any of the options in this dropdown list. Could it be that the HTML code is missing a unique href value ?
<input name="Port 19" value="Uplink" class="ExtendedButton" onclick="SelectFrame('Uplink-200')" id="Port-19" style="width: 84px; display: inline;" type="button">
<script>writeUplinkDropDown()</script>
<div class="dropdown-content">
200G
100G #1
100G #2
</div>
First thing you will need to do is open the dropdown menu. Once the menu is open you can click on any of those options you posted by using any of the following selector examples:
driver.find_elements_by_css_selector('a[onclick="SelectFrame(\"Uplink-200\")"]')
driver.find_elements_by_css_selector('a[onclick="SelectFrame(\"Port-19\")"]')
driver.find_elements_by_css_selector('a[onclick="SelectFrame(\"Port-20\")"]')
Selenium's Select class only works with native <select> elements. Because you have implemented a dropdown with custom HTML, you won't be able to use it.
Instead, in order to select one of the options in your custom dropdown, you'll need to perform each of the actions that a real user would:
clicking the button that opens the dropdown, then
clicking the link for the desired option.
Note: When searching for elements on a page, always try to use the same criteria that a real user would. A real user would look for a link with some meaningful text, e.g., "200G"; they would not go scouring the source code looking for a particular onclick attribute. (What's more, the onclick attribute is a part of the implementation of the page, not the interface, and shouldn't be relied upon as such, as it could change at any time.)
1. Using Selenium
Selenium doesn't provide an explicit method for finding buttons, but you can use CSS or XPath to do that:
driver.find_element_by_css_selector("input[type='button'][value='Uplink']")
driver.find_element_by_xpath("//input[#type = 'button'][#value = 'Uplink']")
To find links, Selenium conveniently provides find_element_by_link_text():
driver.find_element_by_link_text("200G").click()
driver.find_element_by_link_text("100G #1").click()
driver.find_element_by_link_text("100G #2").click()
2. Using Capybara (which uses Selenium)
Bare Selenium can be fickle. The link may not yet be in the DOM. Or it may not yet be visible.
capybara-py addresses these problems transparently:
page.click_button("Uplink")
page.click_link("200G")
page.click_link("100G #1")
page.click_link("100G #2")

Categories

Resources