Python Selenium - 2 buttons with same name - python

I am trying to click on a button but I am not able to do it because there are 2 buttons with similar name class, and I can't click the button I want.
Button 1:
<button class="dropdown-trigger">
<i class="icon2-arrow-down">
::before
Button 2:
<button class="dropdown-trigger is visible-desktop">
<i class="icon2-arrow-down arrow-icon">
::before
I want to click only in button 1, can you help me?

If you're using Chrome browser, (I don't know about other browser's developer's tool, but there must be something similar...) it's easy to pick up unique element.
Press 'F12' key to open Chrome developer's tool. (The page might be refreshed.)
Right click the button you want to focus on.
Click 'Inspect'.
In the developer's tool on the left side of your browser, something will be changed, and there should be a grey box across the HTML source code. (If you move your mouse on it, the button you've inspected should be highlighted)
Right click the grey-colored line then click 'Copy - Copy Selector'. (In your flavor, you can copy other features to find that element)
You can now use the copied selector (or any feature) to find exactly one element you've designated.
If you have any question, please leave comment on this post. thanks!

What happens if you try
driver.find_element_by_css_selector(".dropdown-trigger.visible-desktop").click()
Or you may try getting the element of the two it finds that is displayed...
buttons = driver.find_elements_by_class_name('dropdown-trigger')
button = next(filter(lambda x: x.is_displayed() == True, buttons))
button.click()

Related

Can't click on webpage element using python selenium when used with mobile user-agent

I am trying to automate clicking on the play button of an embedded iframe music player on a webpage, I am coding using python 3 and Selenium to select the element to click.
When the user-agent is changed to replicate a mobile device, a wrapper layer then obscures the button that I can normally click, it asks if I want to listen on the main site or in the browser. I want to listen in the browser, but so far everything I have tried to click the correct element to achieve that, has failed.
I believe I am clicking on the wrong part but cannot find a way to access the correct part.
The inspect window of the browser shows the below for the part of the wrapper I need to click on:
<a class="mobilePrestitial__link sc-font-light" href="#">
Listen in browser
</a>
::before
"
Listen in browser
"
/a>
When I hover over the ::before part it highlights the part in the browser that I believe I need to click, but using right-click to inspect ::before just says 'scroll in view' so I cannot copy whatever the element represents.
My current code is this:
driver.switch_to.default_content()
driver.switch_to.frame(driver.find_element_by_partial_link_text('Listen in browser'))
element = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, '//a[#class="mobilePrestitial__link"]'))
)
element.click()
But it errors without a message, I suspect I need to be clicking on the element presented by ::before but cannot figure how to do that.
I found a workaround and solved this by hiding the wrapper overlay using Selenium in python script to make a Javascript call
driver.execute_script('document.getElementsByClassName("mobilePrestitial")[0].style.display=\"none\"')
once the overlay is hidden with the above code, the original button is accessible in the browser

How to Find an Element to Click on Instagram Unfollow Button

I am making an Instagram bot using selenium and python. I am trying to implement a function which allows a certain amount of followers to be unfollowed. The code navigates to the unfollow screen which has many buttons that say unfollow. The buttons are hard to find with selenium though. If the find_element_by_tag('button') function is used only 3 buttons are found. The button html is:
<button class="_0mzm- sqdOP L3NKy _8A5w5 " type="button">Following</button>
For some reason, I cannot get selenium to select the element. Are there any ways someone can see how to click it?
Try switching to the active element and then clicking on the following
driver. switchTo() . activeElement() ;
And then try the xpath that you tried. This should work
Copy the xpath of the button tag and create reference and use for loop to iterate from one unfollow button onto the next, see my github repository
https://github.com/asadamatic/Unfollow-All-On-Instagram/blob/master/unfollowAll.py

I have a button that im trying to click with selenium however there are more css selectors than buttons

I am trying to click on the 'details' button on https://www.rogers.com/web/totes/wireless/choose-phone. However it seems as though I cant click it. The page seems to be dynamic and so the link does not change.
I have tried selecting the button by link but only to realise it stays on the same link regardless if that button is click. There are 66 elements under the 'details' button when there should only be 32. Therefore when I try selecting any from that list of elements, none work.
phoneDetailsPath = wait.until(EC.presence_of_all_elements_located((By.CSS_SELECTOR, '.select-font.ng-scope')))
phoneDetailsPath[num].click()
I am hoping to be able to store all the 'details' paths into a list and click the button at that index.
In case it helps you can use selector
[ng-click*=gotoDeviceConfigure]
Automationists won't like using javascript but you can execute click as follows:
#first item
driver.execute_script('document.querySelector("[ng-click*=gotoDeviceConfigure]").click();')
# using indices
driver.execute_script('document.querySelectorAll("[ng-click*=gotoDeviceConfigure]")[1].click();')
However, you need to scroll later elements into view and you need to handle dimissing pop-ups about being signed up unless already logged in (I guess).

How to click on an element based on its coordinates with selenium webdriver

So, the web app we're developing has a TV/PC mode, and i'm testing the ability to transit between these two modes. `
def pc_to_tv(self):
pc_to_tv = self.driver.find_element_by_xpath(
'html/body/div[1]/div/topbar/header/div[2]/div[2]/div[1]/button[1]')
pc_to_tv.click()
def tv_to_pc(self):
tv_to_pc = self.driver.find_element_by_xpath(
'html/body/div[1]/div/topbar/header/div[2]/div[2]/div[1]/button[2]')
tv_to_pc.click()`
The problem is, when i switch from pc to tv, the screen "zooms in", making the button appear in the same place it would be without the zoom. so, i can't click on the button with my 'tv_to_pc' method, 'cause instead on clicking on the actual button, it clicks where the button should be.
So, the solution i found was clicking on the button with coordinates, that way i'll actually click on the place i want, instead of clicking on an unclickable place like i was doing.
The thing is, i don't know how to do this, and need help on this matter.
I would suggest that you just click the button using JavaScriptExecutor. It will click it no matter where it is on the page. See How to execute a javascript in a Python webdriver and other questions for more info. The general format is
element = driver.find_element_by_id("someId")
driver.execute_script("arguments[0].click();", element)
Also... you don't want to use XPaths like that. Any XPath that starts at the HTML tag or is more than just a few levels deep is going to be very brittle. Do some googling on selenium xpaths and read some guides for more info.
try moveToElement and then perform click
((JavascriptExecutor) driver).executeScript("arguments[0].scrollIntoView(true);", element);
new Actions(driver).moveToElement(element, x, y).click().perform();
x is xoffset
y is yoffset
Please see that if you use Javascript for click its not going to be native click.

Clicking on dynamically loaded menu with python phantomjs

I want to get the transcript from the youtube video below (I know that there is a way to get the cc captions if available, but often they are not).
I use phantomjs to do this in python.
url = 'https://www.youtube.com/watch?v=wOn8xawC-HQ'
phantom_driver = webdriver.PhantomJS(executable_path="./phantomjs-2.1.1- macosx/bin/phantomjs")
phantom_driver.get(url)
The transcript only appears after clicking on the "More ..." button which I can access with:
phantom_driver.find_element_by_id('action-panel-overflow-button').click()
... this creates a div with the compound class "yt-uix-menu-content yt-ui-menu-content yt-uix-kbd-nav yt-uix-menu-content-hidden" which contains a menu with a <ul> consisting of 4 elements in it.
I need to click on one of these four elements to open the transcript box (specifically, I need to click the button with the compound class "yt-ui-menu-item has-icon yt-uix-menu-close-on-select action-panel-trigger action-panel-trigger-transcript").
However, running
phantom_driver.find_element_by_class_name('action-panel-trigger-transcript').click()
does not work since the element seems still hidden (Element is not currently visible and may not be manipulated).
I believe what I need is clicking on the "More..." button and then directly clicking on the opened menu.
I've looked into this post on select menues and this one on using the html after the click. Neither did quite solve my problem.
What am I missing in my script? Do I need to "refresh" the retrieved html after the click?
"action-panel-overflow-button" is button id not name.
you can click this element by it's xpath
this works fine:
phantom_driver.find_element_by_xpath('//*[#id="action-panel-overflow-button"]').click()
phantom_driver.find_element_by_xpath('//*[#class="yt-ui-menu-item has-icon yt-uix-menu-close-on-select action-panel-trigger action-panel-trigger-transcript"]').click()

Categories