Python - Selenium Unable to locate element on Search button - python

I'm trying to locate and click on a button "Search" on internal website using python selenium.
The element with class = "button":
<a href="javascript:showSearch(true)" title="Search" class="button" id="button_search">
<img src="images/icon_search.gif" alt="">Search
</a>
When click, this button will show a table containing many search filters, and the class changes to "button_active"
<a href="javascript:showSearch(true)" title="Search" class="button_active" id="button_search">
<img src="images/icon_search.gif" alt="">Search
</a>
And xpath is:
//*[#id="button_search"]
locate the css
Packages:
import selenium
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
I've tried all the following code:
search_button = driver.find_element_by_id('button_search')
or
search_button = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//*[#id="button_search"]')))
or
search_button = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, '//*[#title="Search" and #class="button" and #id="button_search"]')))
and many way by ID, LINK_TEXT.... but I always get the same error that:
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"[id="button_search"]"}
(Session info: chrome=79.0.3945.79)
Do you have any ideas why it may not be able to locate this button?
Thank you!
Edit:
I've tried switch_to.frame and it works!
Thank you all!

Related

Python selenium Error "no such element: Unable to locate element"

I've tried for several hours to click a button on webpage with codes below but can't find solution.
I tried to click it with Xpath, full-Xpath, class, but it didn't work.
I heard that 'iframe' can occur error, but I don't see any tags named 'frame'
(Or can the iframe tag be in the document under a different name??)
For your information, when I press the button, it does not direct to a new page, but a pop-up window appears to fill out the contents.
Error mesaage
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"link text","selector":"btnReleaseVendorInfoModal"}
(Session info: chrome=98.0.4758.102)
button
<button type="button" class="btn btn-warning btn-sm" id="btnReleaseVendorInfoModal"> 반출기본정보 수정</button>
Python code
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.keys import Keys
import time
from selenium.common.exceptions import StaleElementReferenceException
# Login
# put id
driver = webdriver.Chrome()
driver.get("https://po-management.net/release/list")
time.sleep(1)
elem = driver.find_element_by_name("username")
elem.send_keys(usernameStr)
elem.send_keys(Keys.RETURN)
time.sleep(2)
# put password
password = driver.find_element_by_xpath('//*[#id="input73"]')
try:
ActionChains(driver).send_keys(Keys.TAB).send_keys(passwordStr).perform()
password.send_keys(passwordStr)
except StaleElementReferenceException:
pass
password.send_keys(Keys.RETURN)
# redirect
time.sleep(3)
url = "https://po-management.net/release/list"
driver.get(url)
# search
time.sleep(1)
search = driver.find_element_by_id("releaseSeqArray")
search.send_keys(vrorder)
search.send_keys(Keys.RETURN)
# click1
time.sleep(1)
driver.find_element_by_link_text(vrorder).click()
# click2
time.sleep(3)
driver.find_element_by_link_text("btnReleaseVendorInfoModal").click()
To click() on the clickable element 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, "button.btn.btn-warning.btn-sm#btnReleaseVendorInfoModal"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='btn btn-warning btn-sm' and #id='btnReleaseVendorInfoModal']"))).click()
Using XPATH and the innerText:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[normalize-space(text())='반출기본정보 수정']"))).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
References
You can find a couple of relevant discussions on NoSuchElementException in:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element while trying to click Next button with selenium
selenium in python : NoSuchElementException: Message: no such element: Unable to locate element

I keep getting a NoSuchElementException in selenium even though the element DOES exist

This is my first scraping project using selenium. I'm trying to download a couple of reddit videos saved in a list using this website.
As you can see, it shows an input tag where I need to enter the url of the video or gif then go to the download page. That input tag has a class name form-control form-control-lg form-control-alternative. So when I try getting that element so I can fill it with a link from a list in Python, it shows a selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: .form-control form-control-lg form-control-alternative error.
You can check yourselves using the Developer Tools and you'll see that that input tag has that class.
Here's my code:
for gif in gif_list:
driver.get('https://keepv.id/reddit-video-downloader')
input_tag = driver.find_element_by_class_name('form-control form-control-lg form-control-alternative')
input_tag.send_keys(gif)
go_button = driver.find_element_by_class_name('btn btn-danger')
go_button.click()
second_button = driver.find_element_by_class_name('btn btn-danger sheen waggle spin')
second_button.click()
WebDriverWait(driver, 5).until(expected_conditions.presence_of_element_located((By.CLASS_NAME, 'row')))
download_button = driver.find_element_by_class_name('btn btn-lg btn-danger mb-3 shadow vdlbtn')
download_button.click()
gif_url = driver.current_url()
download_gif(gif_url)
find_element_by_class_name() accept single class only use css selector instead.
driver.find_element_by_css_selector(".form-control.form-control-lg.form-control-alternative").send_keys(gif)
driver.find_element_by_css_selector(".btn.btn-danger").click()
Or you can use by_id
driver.find_element_by_id("dlURL").send_keys(gif)
driver.find_element_by_id("dlBTN1").click()
Ideally you should use WebDriverWait() and wait for element_to_be_clickable() and following css selecor
WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,".form-control.form-control-lg.form-control-alternative"))).send_keys(gif)
To click go button
WebDriverWait(browser,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,".btn.btn-danger"))).click()
you need to import below libraries
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

Python Finding element by XPath

For reference visit https://rabirius.me/2020/02/14/bird-watching/ (not my website)
You may see a Like button there near a reblog button
I want python to click that but I get an error stating
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div/div/div[2]/a"}
The code i wrote was
for posts in open_links:
bot.get(posts)
sleep(4)
bot.find_element_by_xpath('/html/body/div/div/div[2]/a').click()
sleep(2)
The HTML of the like button is
<div class="wpl-button like">
<a href="#" title="177 bloggers like this." class="like sd-button" rel="nofollow">
<span>Like</span>
</a>
</div>
Any Help would be Appreciated
An iframe is present on the page, so you need to first switch to that iframe and then operate on the element and its recommended to use explicit wait to wait for the element to be present on the page.
You can do it like:
for posts in open_links:
bot.get(posts)
driver.switch_to.frame(bot.find_element_by_tag_name('iframe'))
like_element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//div[contains(#class,'wpl-likebox')]//span[text()='Like']")))
like_element.click()
You need 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

NoSuchElementException: Message: Unable to locate element while trying to locate an element using Selenium and Python

I have a specific login button I can't access with Python Firefox Selenium. It's the login button on this webpage: https://schalter.asvz.ch/tn/lessons/39616
I'm running Ubuntu 16.04, Python 3.5.2, Firefox 65.0 and Selenium 3.141.
I tried several combinations of approaches I found here on stackoverflow including the following:
login = driver.find_element_by_xpath("//*[#class='btn btn-default ng-star-inserted']")
login = driver.find_element_by_xpath("//button[#class='btn btn-default ng-star-inserted']")
login = driver.find_element_by_class_name('btn btn-default ng-star-inserted')
login = driver.find_element_by_xpath("//*[contains(., 'Login')]")
login = driver.find_element_by_name('app-lessons-enrollment-button')
But none of them worked. Always resulting in:
NoSuchElementException: Message: Unable to locate element:
//*[#class='btn btn-default ng-star-inserted']
What is so different with this button? How can I make it work?
This error message...
NoSuchElementException: Message: Unable to locate element: //*[#class='btn btn-default ng-star-inserted']
...implies that the ChromeDriver was unable to locate the desired element through the locator you have used.
Virtually, your first two(2) locators were just perfecto.
However, the desired element is an Angular element so to locate the 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:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn.btn-default.ng-star-inserted[title='Login']"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#class='btn btn-default ng-star-inserted' and #title='Login']"))).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 the below option.
Login=driver.find_element_by_css_selector("button.ng-star-inserted")
Or try this
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,'button.ng-star-inserted'))).click()
You need following imports for option 2.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Following xpath works just fine (tested using selenium java)
//button[#title='Login']
I was able to locate and click the button.
Try the below xpath:
xpath = "//button[#title='Login']"
element = driver.find_element_by_xpath(xpath);
element.click();

How to reach inside <main> tags using selenium Python?

I am using Python 2.7.12 and Selenium 3.0.2.
I wanted to find a tag inside tag <section>, here is the code:
driver = webdriver.Chrome()
driver.get("https://www.semanticscholar.org/")
input_t = driver.find_element_by_xpath('//input[#type="search"]')
input_t.send_keys(keyword)
input_t.send_keys(Keys.ENTER)
target = driver.find_element_by_xpath('//main')
Running this, I got an exception:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//main"}
But actually, there is indeed a tag in the page:
<main class="main-column results" data-reactid=".dyth4mk2kg.0.1.0.1"><div class="controls" data-reactid=".dyth4mk2kg.0.1.0.1.1">
...
</main>
It's just timing issue. You should try using Explicit Waits to wait until main tag loaded and visible after clicking on search button as below :-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome()
driver.get("https://www.semanticscholar.org/")
#Now enter text to search
driver.find_element_by_name("q").send_keys(keyword)
#Now click on search button
driver.find_element_by_css_selector(".search-bar .button").click()
#Now wait until main tag visible
target = WebDriverWait(driver, 30).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "main.main-column.results")))

Categories

Resources