I am trying to click a particular button with Selenium in Python, but am having trouble identifying that particular button. For example, if I was on the google page of this, and I wanted to have the translation bar drop down, how would I go about referencing that specific element. Inspecting it in my browser I see some of what I assume to be its data as:
<div style="clear: both;" aria-controls="uid_0" aria-expanded="false"
class="_LJ _qxg xpdarr _WGh vk_arc" data-fbevent="fastbutton" jsaction="kx.t;
fastbutton: kx.t" role="button" tabindex="0" data-ved="0ahUKEwiwn-6K17XLAhVLWD4KHTk9CTkQmDMILzAA">
However, from this point I'm not sure how I would use the find element by functions to reference what I need to in order to call it properly.
driver.find_element_by_*("?").click()
import unittest
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
#comment
print ("Let's talk about Python.")
driver = webdriver.Firefox()
driver.get("http://www.google.com")
assert "Google" in driver.title
elem = driver.find_element_by_name("q")
elem.send_keys("ignominious")
elem.send_keys(Keys.RETURN)
driver.find_element_by_*("?").click()
assert "No results found." not in driver.page_source
driver.close()
You can use css_selector with the class attribute
driver.find_element_by_css_selector("._LJ._qxg.xpdarr._WGh.vk_arc").click()
Or class_name with any one of the classes
driver.find_element_by_class_name("_LJ").click()
# or
driver.find_element_by_class_name("_qxg").click()
# or
driver.find_element_by_class_name("xpdarr").click()
# or
driver.find_element_by_class_name("_WGh").click()
# or
driver.find_element_by_class_name("vk_arc").click()
Sending click to the element child will also work
driver.find_element_by_class_name("vk_ard").click()
For a better maintainability you should try to work with ids.
With your example the selector would be:
driver.find_element_by_css_selector("#uid_1 > div[role='button']").click()
Do you want to click on arrow.
If yes then below code is working for me:-
driver.manage().timeouts().implicitlyWait(50, TimeUnit.SECONDS);
driver.get("https://www.google.com/");
driver.findElement(By.name("q")).sendKeys("ignominious");
driver.findElement(By.name("q")).sendKeys(Keys.RETURN);
driver.findElement(By.className("vk_ard")).click();
Hope it will help you :)
Related
I have literally tried everything I could think of so far and searched everywhere but haven't been able to find a working solution.
I am trying to automate the process of creating Advertisement Links on a website called Linkvertise. My current code is:
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
chrome_options = Options()
chrome_options.add_argument("user-data-dir=selenium")
browser = webdriver.Chrome(options=chrome_options)
link_to_publish = "https://random.com/2937"
browser.get("https://publisher.linkvertise.com/dashboard#link-create")
# set link
browser.switch_to.frame("link-create-iframe")
browser.find_element(By.ID, "mat-input-0").send_keys(link_to_publish)
# click continue
sleep(3)
browser.find_element(By.CSS_SELECTOR, "body > app-root > lv-link-create-page-component > div > lv-lm-page > div > div.col.p-0 > div > lv-lm-button-wrapper > div > lv-button.mat-tooltip-trigger > a").click()
# toggle off visibility
sleep(3)
browser.find_element(By.CSS_SELECTOR, "#mat-slide-toggle-2 > label > div").click()
# set title
sleep(3)
browser.find_element(By.ID, 'mat-input-8')
You need to run it once and login manually, it will then store the session in the current directory and you can start running the full program.
I still have the sleep times in there as I wanted the process to be a little slower.
My issue:
The element is on the second page of the iframe (image attached). I have already successfully access other elements within that iframe, even on the same page. But for some reason I am not able to add the link description (bottom of my screenshot).
enter image description here
Does anyone know why that is?
I will also provide some dummy login details if anyone is willing to check, I would highly appreciate it!!
Email: pschw1#tellofon.com
Password: Pschw123!
HTML Code of the element I'm trying to access:
<input lvpreventdoublespacesdoublenewlines="" autocomplete="off" formcontrolname="btn_text" matinput="" spellcheck="false" class="mat-input-element mat-form-field-autofill-control ng-touched ng-pristine ng-invalid cdk-text-field-autofill-monitored highlight-textarea" maxlength="50" placeholder="Beschreibe deinen Link präzise in wenigen Worten" required="" id="mat-input-22" data-placeholder="Beschreibe deinen Link präzise in wenigen Worten" aria-required="true">
What I tried so far:
using higher sleep delays incase the error just came from the content not loading in time
leaving the iframe incase the element wasn't actually inside it
finding element by ID, class name, css selector, xpath
I've searched for help in other online forums and even looked for help on fiverr, but nobody was able to provide a solution yet.😅
This element's ID mat-input-8 is a dynamic one, it is keep on changing everytime, you can use the below one:
driver.find_element(By.CSS_SELECTOR, ".input-area.single-line-input input").send_keys("something for testing")
Trying to identify a javascript button on a website and press it to extend the page.
The website in question is the tencent appstore after performing a basic search. At the bottom of the page is a button titled "div.load-more-new" where upon pressing will extend the page with more apps.
the html is as follows
<div data-v-33600cb4="" class="load-more-btn-new" style="">
<a data-v-33600cb4="" href="javascript:void(0);">加载更多
<i data-v-33600cb4="" class="load-more-icon">
</i>
</a>
</div>
At first I thought I could identify the button using BeautifulSoup but all calls to find result as empty.
from selenium import webdriver
import BeautifulSoup
import time
url = 'https://webcdn.m.qq.com/webapp/homepage/index.html#/appSearch?kw=%25E7%2594%25B5%25E5%25BD%25B1'
WebDriver = webdriver.Chrome('/chromedriver')
WebDriver.get(url)
time.sleep(5)
# Find using BeuatifulSoup
soup = BeautifulSoup(WebDriver.page_source,'lxml')
button = soup.find('div',{'class':'load-more-btn-new'})
[0] []
After looking around here, it became apparent that even if I could it in BeuatifulSoup, it would not help in pressing the button. Next I tried to find the element in the driver and use .click()
driver.find_element_by_class_name('div.load-more-btn-new').click()
[1] NoSuchElementException
driver.find_element_by_css_selector('.load-more-btn-new').click()
[2] NoSuchElementException
driver.find_element_by_class_name('a.load-more-new.load-more-btn-new[data-v-33600cb4]').click()
[3] NoSuchElementException
but all return with the same error: 'NoSuchElementException'
Your selections wont work, cause they do not point on the <a>.
This one selects by class name and you try to click the <div> that holds your <a>:
driver.find_element_by_class_name('div.load-more-btn-new').click()
This one is very close but is missing the a in selection:
driver.find_element_by_css_selector('.load-more-btn-new').click()
This one try to find_element_by_class_name but is a wild mix of tag, attribute and class:
driver.find_element_by_class_name('a.load-more-new.load-more-btn-new[data-v-33600cb4]').click()
How to fix?
Select your element more specific and nearly like in your second apporach:
driver.find_element_by_css_selector('.load-more-btn-new a').click()
or
driver.find_element_by_css_selector('a[data-v-33600cb4]').click()
Note:
While working with newer selenium versions you will get DeprecationWarning: find_element_by_ commands are deprecated. Please use find_element()*
from selenium.webdriver.common.by import By
driver.find_element(By.CSS_SELECTOR, '.load-more-btn-new a').click()
I have homework to make a program in python with Selenium to send an email on hotmail. Everything was working fine till I had to find the "New Message" button (or any other button on that page to be honest)
Im constantly getting selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element:
I tried By : Class,Xpath,FullXpath,Css Selector. Can't find the name or Id
using the inspector.
I tried to make it wait with time.sleep
I really don't know what to do.
My code is here:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
driver = webdriver.Chrome(executable_path='C:\SeleniumDriver\chromedriver.exe')
driver.get("https://login.live.com/")
searchField = driver.find_element_by_name("loginfmt")
searchField.send_keys("")
nextButton = driver.find_element_by_id("idSIButton9").click()
passfield = driver.find_element_by_id("i0118")
passfield.send_keys("")
time.sleep(1)
signInButton = driver.find_element_by_xpath("//*[#id='idSIButton9']").click()
time.sleep(2)
try:
nobutton = driver.find_element_by_xpath("//*[#id='idBtn_Back']").click()
finally:
time.sleep(2)
appbutton = driver.find_element_by_xpath("//*[#id='O365_MainLink_NavMenu']").click()
time.sleep(10)
outlookbutton = driver.find_element_by_xpath("//*[#id='O365_AppTile_Mail']").click()
time.sleep(15)
newmessageButton = driver.find_element_by_xpath("//*[#id='app']/div/div[2]/div[2]/div[1]/div/div[1]/div/span/div/div/div/div/div[1]/div[1]").click()
time.sleep(6)
Requested HTML:
<div class="XayzgKk2Ga7sG02AhkQKJ"><div class="_1qPqjoFrRhZTOpwH-IJ2UP"><button type="button" class="ms-Button ms-Button--icon is-checked _3YkNJYKjMvYWaDLQ_t6D9- root-157" title="Toggle Left Pane" aria-expanded="true" aria-label="Toggle Left Pane" data-is-focusable="true"><span class="ms-Button-flexContainer flexContainer-158" data-automationid="splitbuttonprimary"><i data-icon-name="GlobalNavButton" aria-hidden="true" class="ms-Button-icon icon-167"></i></span></button></div><div class="_2nxYvsT9VmpG24V7lwcfcu"><div class=""><div class=""><button type="button" class="ms-Button GJoz3Svb7GjPbATIMTlpL _2W_XxC_p1PufyiP8wuAvwF lZNvAQjEfdlNWkGGuJb7d ms-Button--commandBar Gf6FgM99ZJ9S8H48pFMdB _3o6O4cjBEmQ4Q19oQJZZiF root-168" data-is-focusable="true"><span class="ms-Button-flexContainer flexContainer-158" data-automationid="splitbuttonprimary"><i data-icon-name="ComposeRegular" aria-hidden="true" class="ms-Button-icon _1y8YJ1XNBkLjckwryuEz2e icon-172"><span role="presentation" aria-hidden="true" class="w_jrWE2b2u-icz2udikRM"><svg class="_9fiU2J67uJPVP0DBdOFMW" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M14.85 1.85a.5.5 0 10-.7-.7l-8 8L6 10l.85-.15 8-8z"></path><path d="M4.5 2A2.5 2.5 0 002 4.5v7A2.5 2.5 0 004.5 14h7a2.5 2.5 0 002.5-2.5v-5a.5.5 0 00-1 0v5c0 .83-.67 1.5-1.5 1.5h-7A1.5 1.5 0 013 11.5v-7C3 3.67 3.67 3 4.5 3h5a.5.5 0 000-1h-5z"></path></svg></span></i><span class="ms-Button-textContainer textContainer-159"><span class="ms-Button-label uHWG8PYRNYDO2895_TmUG label-170" id="id__6">New message</span></span></span></button></div></div></div></div>
The "New message" button would be this selector in xpath:
"//button[contains(., 'New message')]"
Also, you might have an easier time choosing the correct selector if you use a record/playback/export tool to generate a script for you. Since you're already using Python, I recommend the SeleniumBase Recorder: https://github.com/seleniumbase/SeleniumBase/blob/master/help_docs/recorder_mode.md (It should help you generate a full script with selectors more easily.)
The reason is, once you click on outlook on first windows a new tab is opened and there we have a new message button. So in order to click on that, you would have to make sure that Selenium is switching to the new tab.
first_win_handle = driver.current_window_handle
outlookbutton = driver.find_element_by_xpath("//*[#id='O365_AppTile_Mail']")
outlookbutton.click()
all_win_handles = driver.window_handles
driver.switch_to.window(all_win_handles[1])
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[text()='New message']/ancestor::button"))).click()
Imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
You are trying to find the element by id, but the element does not have an id. So that does not work.
You will either have to ensure the element gets that correct id, or use a different way to locate it.
You might try finding it by Css Selector:
'button[data-automationid="splitbuttonprimary"]'
Make sure to use the right quotes. Try this in the inspector first and you should find it. If you do not: it will not work, no matter the code.
If you see multiple hits then the css is not specific enough, and you will need to find a more specific way to locate it.
That selector basically means: an element of type "button" with attribute "data-automationid" with value "splitbuttonprimary". You can read more about locating specicif elements, css selectors, html elements and attributes here
I am new to selenium here. I am trying to use selenium to click a 'more' button to expand the review section everytime after refreshing the page.
The website is TripAdvisor. The logic of more button is, as long as you click on the first more button, it will automatically expand all the review sections for you. In other words, you just need to click on the first 'more' button.
All buttons have a similar class name. An example is like taLnk.hvrIE6.tr415411081.moreLink.ulBlueLinks. Only the numbers part changes everytime.
The full element look like this:
<span class="taLnk hvrIE6 tr413756996 moreLink ulBlueLinks" onclick=" var options = {
flow: 'CORE_COMBINED',
pid: 39415,
onSuccess: function() { ta.util.cookie.setPIDCookie(2247); ta.call('ta.servlet.Reviews.expandReviews', {type: 'dummy'}, ta.id('review_413756996'), 'review_413756996', '1', 2247);; window.location.hash = 'review_413756996'; }
};
ta.call('ta.registration.RegOverlay.show', {type: 'dummy'}, ta.id('review_413756996'), options);
return false;
">
More </span>
I have tried several ways to get the button click. But since it is an onclick event wrapped by span, I can't successfully get it clicked.
My last version looks like this:
driver = webdriver.Firefox()
driver.get(newurl)
page_source = driver.page_source
soup = BeautifulSoup(page_source)
moreID = soup.find("span", class_=re.compile(r'.*\bmoreLink\b.*'))['class']
moreID = '.'.join(moreID[0:(len(moreID)+1)])
moreButton = 'span.' + moreID
button = driver.find_element_by_css_selector(moreButton)
button.click()
time.sleep(10)
However, I keep getting the error message like this:
WebDriverException: Message: Element is not clickable at point (318.5,
7.100006103515625). Other element would receive the click....
Can you advise me on how to fix the problem? Any help will be appreciated!
WebDriverException: Message: Element is not clickable at point (318.5, 7.100006103515625). Other element would receive the click....
This error to be occur when element is not in the view port and selenium couldn't click due to some other overlay element on it. In this case you should try one of these following solution :-
You can try using ActionChains to reach that element before click as below :-
from selenium.webdriver.common.action_chains import ActionChains
button = driver.find_element_by_css_selector(moreButton)
ActionChains(button).move_to_element(element).click().perform()
You can try using execute_script() to reach that element before click as :-
driver.execute_script("arguments[0].scrollIntoView(true)", button)
button.click()
You can try using JavaScript::click() with execute_script() but this JavaScript::click() defeats the purpose of the test. First because it doesn't generate all the events like a real click (focus, blur, mousedown, mouseup...) and second because it doesn't guarantee that a real user can interact with the element. But to get rid from this issues you can consider it as an alternate solution.
driver.execute_script("arguments[0].click()", button)
Note:- Before using these options make sure you're trying to interact with correct element using with correct locator, otherwise WebElement.click() would work well after wait until element visible and clickable using WebDriverWait.
Try using an ActionChains:
from selenium.webdriver.common.action_chains import ActionChains
# Your existing code here
# Minus the `button.click()` line
ActionChains(driver).move_to_element(button).click().perform()
I have used this technique when I need to click on a <div> or a <span> element, rather than an actual button or link.
I have a HTML code like this:
<div class="links nopreview"><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://REFLECTION/INSTANCE/_CS_Data/null">Home</a></span> • <span><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://SITEADMIN/_CS_Site">Setup</a></span> • </span><span><a
title="Sign Out" class="csiAction csiActionLink">Sign Out</a></span></div>
I would like to click on the link that has the text Home. As this Home link appears after login, I have a code like this:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import re
browser = webdriver.Firefox() # Get local session of firefox
browser.get("http://myServer/WebAccess/login.html") # Load App page
elem = browser.find_element_by_name("LoginID") # Find the Login box
elem.send_keys("Administrator")
elem = browser.find_element_by_name("Password") # Find the Password box
elem.send_keys("Administrator" + Keys.RETURN)
#try:
elem = browser.find_element_by_link_text("Home")
elem.click()
The part till login works great. However the last but one line is problematic
elem = browser.find_element_by_link_text("Home")
It raises this NoSuchElementException where the Home link is there as you can see from the HTML code.
raise exception_class(message, screen, stacktrace)
NoSuchElementException: Message: u'Unable to locate element: {"method":"link text","selector":"Home"}'
Any guidance as to what I am doing wrong, please?
Have you tried adding an implicit wait to this so that it waits instead of running to quickly.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import re
browser = webdriver.Firefox() # Get local session of firefox
browser.implicitly_wait(10) #wait 10 seconds when doing a find_element before carrying on
browser.get("http://myServer/WebAccess/login.html") # Load App page
elem = browser.find_element_by_name("LoginID") # Find the Login box
elem.send_keys("Administrator")
elem = browser.find_element_by_name("Password") # Find the Password box
elem.send_keys("Administrator" + Keys.RETURN)
#try:
elem = browser.find_element_by_link_text("Home")
elem.click()
The implicitly_wait call makes the browser poll until the item is on the page and visible to be interacted with.
The most common issues with NoSuchElementException while the element is there are:
the element is in different window/frame, so you've to switch to it first,
your page is not loaded or your method of page load is not reliable.
Solution could include:
check if you're using the right frame/window by: driver.window_handles,
write a wait wrapper to wait for an element to appear,
try XPath instead, like: driver.find_element_by_xpath(u'//a[text()="Foo"]').click(),
use pdb to diagnose your problem more efficiently.
See also: How to find_element_by_link_text while having: NoSuchElement Exception?
Maybe the element you are looking for doesn't exactly match that text string?
I know it can be tricky if it looks like it does on-screen, but sometimes there are oddities embedded like this simple markup "Home" or "Home" which makes the first char italic:
"<i>H</i>ome" is visually identical to "<em>H</em>ome" but does not match text.
Edit: after writing the above answer, I studied the question closer and discovered the HTML sample does show "Home" in plain text, but was not visible due to long lines not wrapping. So I edited the OP to wrap the line for readability.
New observation: I noticed that the Logout element has a "title" attribute, but the Home link element lacks such--try giving it one and using that.
Try adding an implicit wait to this in order to wait, instead of running too quickly.
Or
else you can import time and use time.sleep(25)