Trouble selecting google one box tab in selenium - python

going to https://www.google.com/search?q=tennis a google one box comes up for scores, I'm trying to click on the tabs and (Women's Singles, Men's Doubles etc) and having no luck. I've tried all methods, xpath, classname, partial link text, css selector.
any help would be appreciated!!!

The desired element is a JavaScript enabled element, so ideally, to click on the element you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Clicking Women's Singles:
driver.get('https://www.google.com/search?q=tennis')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[#jsslot]//span//span[contains(., 'Women') and contains(., 'Singles')]"))).click()
Clicking Men's Doubles:
driver.get('https://www.google.com/search?q=tennis')
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//span[#jsslot]//span//span[contains(., 'Men') and contains(., 'Doubles')]"))).click()
Note: You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

I always use this method to set the XPath in Selenium based Python projects.
Click F12 after opening the link
In Elements, Click Ctrl + F. Now search some unique term in the page. I gave Men's Singles and this snippet came up.
<div class="SVWlSe FZzi2e" jsslot="">
<span jsslot="">
<div aria-controls="_dtAkYIqaMLraz7sPnrW54A435_0"
id="_dtAkYIqaMLraz7sPnrW54A434_0">
<span>
<span>Men's Singles</span>
</span>
</div>
</span>
</div>
Now right-click the snippet to get the XPath format or use the XPath Syntax. Here, the XPath is //div[#class='SVWlSe FZzi2e']. To find whether the attribute value is unique, I would suggest you to search within elements again with the value.
Notice that I used the class attribute instead of the aria-controls and id attributes since id and aria-controls changed over time.

Related

Selenium Click button whitout id

i have to click the input type="button" element of the first li, but i can not refer to the id of the li, since it changes every time i i open the website, this is what i tried
driver.find_elements_by_xpath('//input[data-componentname="gender"]').get(0).click()
and it gives me this error:
AttributeError: 'list' object has no attribute 'get'
if i remove the get part, this is the error:
AttributeError: 'list' object has no attribute 'click'
This is the code, like i said, i have to click the first input without referring to the id
<ul data-componentname="gender">
<li id="78ece221-1b64-4124-8483-80168f21805f" class="">
<input type="button">
<span>Uomo</span>
</li>
<li id="2678a655-b610-41e0-8e7f-bad58fbcb1b3" class="">
<input type="button">
<span>Donna</span>
</li>
</ul>
To click on the element Uomo you need to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "ul[data-componentname='gender'] li:nth-of-type(1) span"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//ul[#data-componentname='gender']//span[text()='Uomo']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Browser Snapshot:
find_elements method return a list of web elements.
The first member of the list can be received by simple indexation i.e. list_object[0]
Also, since you want to get the first element matching the //input[data-componentname="gender"] locator you can simply use find_element method.
So, instead of
driver.find_elements_by_xpath('//input[data-componentname="gender"]').get(0).click()
You can use
driver.find_element_by_xpath('//input[data-componentname="gender"]').click()
Or
driver.find_elements_by_xpath('//input[data-componentname="gender"]')[0].click()
UPD
well, you tried to use a wrong locator.
This should work:
driver.find_element_by_xpath("//ul[#data-componentname='gender' ]//span[text()='Uomo']/../input").click()
You can also click the element containing the "Uomo" text itself as well
driver.find_element_by_xpath("//ul[#data-componentname='gender' ]//span[text()='Uomo']").click()
You can include the first li if you only want that. For example:
driver.find_element_by_xpath('//input[data-componentname="gender"]/li[1]')
otherwise if you want the list then you can do
driver.find_elements_by_css_selector('input[data-componentname="gender"] > li')
and do the .get() according to which button you want to click

How to locate and click the textarea element using Selenium and Python

I'm using Selenium with python and have been trying to click a text box, and input a message.
The text box's HTML looks like this:
<div class="tw-block tw-border-radius-large tw-pd-0">
<div class="tw-relative">
<div class="chat-input__textarea">
<textarea data-a-target="chat-input" data-test-selector="chat-input" class="tw-block tw-
border-radius-medium tw-font-size-6 tw-full-width tw-textarea tw-textarea--no-resize"
autocomplete="Messenger-chat" maxlength="500" placeholder="Send a message" rows="1"
style="padding-right: 3.5rem;"></textarea>
</div>
</div>
</div>
I have been trying to select it by css selector with this code:
time.sleep(3)
input_box = browser.find_element_by_css_selector(".textarea")
input_box.click()
for ch in message:
input_box.send_keys(ch)
input_box.send_keys(Keys.ENTER)
It keeps giving me a NoSuchElement. As you can see I don't really know what I am really doing- please help thanks :)
.texarea is not going to find any element:
. indicates that the selector should look for the proceeding value in the className of an element.
So, you are telling the selector to look for an element with className textarea.
You are confusing className selector with a tagname selector. If you want to get it by tagname, you just use the tagname without any dot(.), so:
find_element_by_css_selector("textarea")
This would return the first textarea element it finds, which may or may not be what you want. To make it more precise you can do:
find_element_by_css_selector("textarea.tw-block.tw-
border-radius-medium.tw-font-size-6.tw-full-width.tw-textarea.tw-textarea--no-resize")
Notice how in the second version there are multiple dots(.) in the selector, telling the engine to search for an element of tagname textarea with classNames: tw-block tw-
border-radius-medium tw-font-size-6 tw-full-width tw-textarea tw-textarea--no-resize. Each individual className is seperated by a space in the Html markup, so you use a dot(.) to tell the selector to chain those classNames together.
If by chance you have multiple textarea's with all the same classNames as above, you'd need to find some kind of unique identifier for the textarea you want. So the selector provided by KunduK is a good example of that.
Perhaps this link will help you to learn more about css selectors: (https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors)
As per the HTML the element is a <textarea> element. So to identify the element the relevant code would have been either of the following:
browser.find_element_by_tag_name("textarea")
browser.find_element_by_css_selector("textarea[attribute_name='attribute_value']")
Solution
Ideally, to identify and click within the desired element you have to induce WebDriverWait for the element_to_be_clickable() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
input_box = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "textarea[data-a-target='chat-input'][data-test-selector='chat-input'][placeholder='Send a message']")))
input_box.click()
Using XPATH:
input_box = WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//textarea[#data-a-target='chat-input' and #data-test-selector='chat-input'][#placeholder='Send a message']")))
input_box.click()
Note : You have to add the following imports:
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Your css selector is wrong .textarea in css selector identify the class name.
Try below css selector.
input_box = browser.find_element_by_css_selector("textarea[data-a-target='chat-input']")

How to locate a tag by text in its child tag

I am new to Webelement and selenium, can anyone help me on how to locate element below , using text "Hotel Wahington":
<a class="hotel_name_link url" href="/hotel/nl/washington.html?label=gen173nr-1FCAEoggI46AdIM1gEaFCIAQGYATG4ARjIAQzYAQHoAQH4AQKIAgGoAgS4Apyz__EFwAIB&sid=1b691d9ad57ac7ee7c3d40dac2f7f488&dest_id=-2140479&dest_type=city&group_adults=2&group_children=0&hapos=1&hpos=1&no_rooms=1&sr_order=popularity&srepoch=1581242789&srpvid=87de4712b9a90095&ucfs=1&from=searchresults;highlight_room=#hotelTmpl" target="_blank" rel="noopener">
<span class="sr-hotel__name" data-et-click=" ">Hotel Washington</span>
<span class="invisible_spoken">Opens in new window</span>
</a>
Adding the original link below :
https://www.booking.com/searchresults.html?label=gen173nr-1FCAEoggI46AdIM1gEaFCIAQGYATG4ARjIAQzYAQHoAQH4AQKIAgGoAgS4ApSSgPIFwAIB&sid=dcd3ff4c30abfd0bc264d5ae4a4c1d7a&sb=1&sb_lp=1&src=index&src_elem=sb&error_url=https%3A%2F%2Fwww.booking.com%2Findex.html%3Flabel%3Dgen173nr-1FCAEoggI46AdIM1gEaFCIAQGYATG4ARjIAQzYAQHoAQH4AQKIAgGoAgS4ApSSgPIFwAIB%3Bsid%3Ddcd3ff4c30abfd0bc264d5ae4a4c1d7a%3Bsb_price_type%3Dtotal%26%3B&sr_autoscroll=1&ss=hotel+washington&is_ski_area=0&checkin_year=&checkin_month=&checkout_year=&checkout_month=&group_adults=2&group_children=0&no_rooms=1&b_h4u_keep_filters=&from_sf=1
To select anchor tag based on text "Hotel Wahington" use the following xpath.
Use following Xpath
driver.find_element_by_xpath("//a[#class='hotel_name_link url' and contains(.,'Hotel Washington')]").click()
Or following css selector.
driver.find_element_by_css_selector("a.hotel_name_link.url[href*='/hotel/nl/washington']").click()
Or partial link text.
driver.find_element_by_partial_link_text("Hotel Washington").click()
Tryout this xpath:
//span[text()='Hotel Washington']/parent::a
Also note that the method "find_element_by_xpath()" in the answers is from version 4 of Selenium which is still in Alpha testing phase. You will be most likely using Selenium version 3. The valid code for version 3 would be:
driver.findElement(By.xpath("//span[text()='Hotel Washington']/parent::a")),click();
Using xpath you can go to parent element with ..
driver.find_element_by_xpath('//span[.="Hotel Washington"]/..')
Or locate an element which has specific text
driver.find_element_by_xpath('//a[span[.="Hotel Washington"]]')
Use the
xPath = //*[contains(#text(),'Hotel Wahington')]
OR
//a[#class='hotel_name_link url']//*[contains(#text(),'Hotel Wahington')]
You can locate an element using text only. You can try below solution:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
element = WebDriverWait(driver, 50).until(
EC.presence_of_element_located((By.XPATH, "//span[contains(., 'Hotel Washington')]")))
element.click()

How to locate and click the element when the innerText contains leading and trailing white-space characters using Selenium and Python

I want to locate (and click) the "Reoni" element, but I do not know what function to use it for
I tried with
driver.find_element_by_class_name("oe_menu_leaf")
and
driver.find_element_by_class_name("oe_menu_text")
but then selenium raise an error element cant be located,
and I tried
driver.find_element_by_link_text("Reoni")
This is the element I want to locate:
<a href="/web#menu_id=86&action=99" class="oe_menu_leaf" data-menu="86" data-action-model="ir.actions.act_window" data-action-id="99">
<span class="oe_menu_text">
Reoni
</span>
</a>
and full html:
If I was not clear enough or if you needed my code, please let me know.
As the desired element is a dynamic element you need to induce WebDriverWait for the desired element to be clickable and you can use either of the following solutions:
Using CSS_SELECTOR:
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "a.oe_menu_leaf[href*='/web#menu_id=']>span.oe_menu_text"))).click()
Using XPATH and text():
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='oe_menu_leaf' and starts-with(#href,'/web#menu_id=')]/span[#class='oe_menu_text' and text()='Reoni']"))).click()
Using XPATH and normalize-space():
WebDriverWait(browser, 20).until(EC.element_to_be_clickable((By.XPATH, "//a[#class='oe_menu_leaf' and contains(#href,'/web#menu_id=')]/span[#class='oe_menu_text' and normalize-space()='Reoni']"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Reference
You can find a relevant detailed discussion in:
Selenium “selenium.common.exceptions.NoSuchElementException” when using Chrome
Try something like this:
Clicking the button
From Chrome :
Right click "inspect" on the item you are trying to find the xpath.
Right click on the highlighted area on the console.
Go to Copy xpath
selectElem=browser.find_element_by_xpath('x-path-here').click()
Reading Values Only
from bs4 import BeautifulSoup
innerHTML = browser.execute_script("return document.body.innerHTML")
soup = BeautifulSoup(str(innerHTML.encode('utf-8').strip()), 'lxml')
value = soup.find('span', attrs={'class':'fxst-calendarpro fxst-table-s1'}).text

How to use the onclick event as a selector in webdriver?

Here is the element:
<label title="Place Order" style="cursor: pointer" onclick="AjaxPageLoad(fno, 'FNOOrder');">Place Order<div></div></label>
I am trying to click on this but need to use the #onclick as the main differentiator. I read the other similar questions but can't seem to get this to work:
driver.find_element_by_xpath("//a[contains(#onclick,'fno')]").click()
driver.find_element_by_xpath("//a[contains(#onclick,'FNOOrder')]").click()
Error I get:
ElementNotInteractableException: Message: Element <a id="lnkFNO" class="active" href="javascript:void(0)"> could not be scrolled into view
But the element is visible so I assume that the xpath must be wrong.
As per the HTML you have shared to click on the desired element using the onclick event you have to induce WebDriverWait and you can use the follwing solution:
xpath using onclick:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[#onclick=\"AjaxPageLoad(fno, 'FNOOrder');\"]"))).click()
xpath using onclick and title:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[#title='Place Order'][#onclick=\"AjaxPageLoad(fno, 'FNOOrder');\"]"))).click()
xpath using onclick, title and innerHTML:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//label[#title='Place Order'][#onclick=\"AjaxPageLoad(fno, 'FNOOrder');\"][contains(.,'Place Order')]"))).click()
Note : You have to add the following imports :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
Try to use css selector, if you are familiar with web development, it should be easier.
driver.find_element_by_css_selector("label[onclick*=fno]").click()
Above code will select label with onclick argument contains 'fno' string. Here you can find all selectors: https://www.w3schools.com/cssref/css_selectors.asp

Categories