I am trying to click to an object that I select with Xpath, but there seems to be problem that I could not located the element. I am trying to click accept on the page's "Terms of Use" button. The code I have written is as
driver.get(link)
accept_button = driver.find_element_by_xpath('//*[#id="terms-ok"]')
accept_button.click()
prov = driver.find_element_by_id("province-region")
prov.click()
Here is the HTML code I have:
And I am getting a "NoSuchElementException". My goal is to click this "Kabul Ediyorum" button at the bottom of the HTML code. I started to think that we have some restrictions on the tasks we could do on that page. Any ideas ?
Not really sure what the issue might be.
But you could try the following:
Try to locate the element by its visible text
accept_button = driver.find_element_by_xpath("//*[text()='Kabul Ediyorum']").click()
Try with ActionChains
For that you need to import ActionChains
from selenium.webdriver.common.action_chains import ActionChains
accept_button = driver.find_element_by_xpath("//*[text()='Kabul Ediyorum']")
actions = ActionChains(driver)
actions.click(on_element=accept_button).perform()
Also make sure you have implicitly wait
# implicitly wait
driver.implicitly_wait(10)
Or explicit wait
element = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//*[text()='Kabul Ediyorum']"))).click()
Hope this helped!
Related
I am trying to click this button to export my data as a csv file. I'm using Selenium on python.
I can not figure out how to press the button because there is no id or name and the link changes every time.
Thanks in advance!
You have to scroll to that element. Like this:
from selenium.webdriver.common.action_chains import ActionChains
element = driver.find_element_by_xpath("//a[contains(#href,'swissadme.csv')]")
actions = ActionChains(driver)
actions.move_to_element(element).perform()
element.click()
If the locator above not enough try this instead:
"//a[contains(#href,'results/50881847/swissadme.csv')]"
See if this works:-
elm = driver.find_element_by_xpath(".//div[contains(text(),'Retrieve date:')]/a[contains(#href,''swissadme.csv)]")
driver.execute_script("arguments[0].scrollIntoView(true);",elm);
elm.click()
I am trying to scrape information on a website where the information is not immediately present. When you click a certain button, the page begins to load new content on the bottom of the page, and after it's done loading, red text shows up as "Assists (At Least)". I am able to find the first button "Go to Prop builder", which doesn't immediately show up on the page, but after the script clicks the button, it times out when trying to find the "Assists (At Least)" text, in spite of the script sleeping and being present on the screen.
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
import time
from bs4 import BeautifulSoup
driver = webdriver.Chrome()
driver.get('https://www.bovada.lv/sports/basketball/nba')
# this part succeeds
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located(
(By.XPATH, "//span[text()='Go to Prop builder']")
)
)
element.click()
time.sleep(5)
# this part fails
element2 = WebDriverWait(driver, 6).until(
EC.visibility_of_element_located(
(By.XPATH, "//*[text()='Assists (At Least)']")
)
)
time.sleep(2)
innerHTML = driver.execute_script('return document.body.innerHTML')
driver.quit()
soup = BeautifulSoup(innerHTML, 'html.parser')
The problem is the Assist element is under a frame. You need to switch to the frame like this:
frame = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME,"player-props-frame")))
driver.switch_to.frame(frame)
Increase the timeout to confirm the timeout provided is correct, You can also confirm using debug mode. If still issue persist, please check "Assists (At Least)" element do not fall under any frame.
You can also share the DOM and proper error message if issue not resolved.
I have a couple of suggestions you could try,
Make sure that the content loaded at the bottom of the is not in a frame. If it is, you need to switch to the particular frame
Check the XPath is correct, try the XPath is matching from the Developer Console
Inspect the element from the browser, once the Developer console is open, press CTRL +F and then try your XPath. if it's not highlighting check frames
Check if there is are any iframes in the page, search for iframe in the view page source, and if you find any for that field which you are looking for, then switch to that frame first.
driver.switch_to.frame("name of the iframe")
Try adding a re-try logic with timeout, and a refresh button if any on the page
st = time.time()
while st+180>time.time():
try:
element2 = WebDriverWait(driver, 6).until(
EC.visibility_of_element_located(
(By.XPATH, "//*[text()='Assists (At Least)']")
)
)
except:
pass
The content you want is in an iFrame. You can access it by switching to it first, like this:
iframe=driver.find_element_by_css_selector('iframe[class="player-props-frame"]')
driver.switch_to.frame(iframe)
Round brackets are the issue here (at least in some cases...). If possible, use .contains selector:
//*[contains(text(),'Assists ') and contains(text(),'At Least')]
I am having trouble selecting a load more button on a Linkedin page. I receive this error in finding the xpath: selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element
I suspect that the issue is that the button is not visible on the page at that time. So I have tried actions.move_to_element. However, the page scrolls just below the element, so that the element is no longer visible, and the same error subsequently occurs.
I have also tried move_to_element_with_offset, but this hasn't changed where the page scrolls to.
How can I scroll to the right location on the page such that I can successfully select the element?
My relevant code:
import parameters
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
ChromeOptions = webdriver.ChromeOptions()
driver = webdriver.Chrome('C:\\Users\\Root\\Downloads\\chromedriver.exe')
driver.get('https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin')
sleep(0.5)
username = driver.find_element_by_name('session_key')
username.send_keys(parameters.linkedin_username)
sleep(0.5)
password = driver.find_element_by_name('session_password')
password.send_keys(parameters.linkedin_password)
sleep(0.5)
sign_in_button = driver.find_element_by_xpath('//button[#class="btn__primary--large from__button--floating"]')
sign_in_button.click()
driver.get('https://www.linkedin.com/in/kate-yun-yi-wang-054977127/?originalSubdomain=hk')
loadmore_skills=driver.find_element_by_xpath('//button[#class="pv-profile-section__card-action-bar pv-skills-section__additional-skills artdeco-container-card-action-bar artdeco-button artdeco-button--tertiary artdeco-button--3 artdeco-button--fluid"]')
actions = ActionChains(driver)
actions.move_to_element(loadmore_skills).perform()
#actions.move_to_element_with_offset(loadmore_skills, 0, 0).perform()
loadmore_skills.click()
After playing around with it, I seem to have figured out where the problem is stemming from. The error
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//button[#class="pv-profile-section__card-action-bar pv-skills-section__additional-skills artdeco-container-card-action-bar artdeco-button artdeco-button--tertiary artdeco-button--3 artdeco-button--fluid"]"}
(Session info: chrome=81.0.4044.113)
always correctly states the problem its encountering and as such it's not able to find the element. The possible causes of this include:
Element not present at the time of execution
Dynamically generated
content Conflicting names
In your case, it was the second point. As the content that is displayed is loaded dynamically as you scroll down. So When it first loads your profile the skills sections aren't actually present in the DOM. So to solve this, you simply have to scroll to the section so that it gets applied in the DOM.
This line is the trick here. It will position it to the correct panel and thus loading and applying the data to the DOM.
driver.execute_script("window.scrollTo(0, 1800)")
Here's my code (Please change it as necessary)
from time import sleep
# import parameters
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
ChromeOptions = webdriver.ChromeOptions()
driver = webdriver.Chrome('../chromedriver.exe')
driver.get('https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin')
sleep(0.5)
username = driver.find_element_by_name('session_key')
username.send_keys('')
sleep(0.5)
password = driver.find_element_by_name('session_password')
password.send_keys('')
sleep(0.5)
sign_in_button = driver.find_element_by_xpath('//button[#class="btn__primary--large from__button--floating"]')
sign_in_button.click()
driver.get('https://www.linkedin.com/in/kate-yun-yi-wang-054977127/?originalSubdomain=hk')
sleep(3)
# driver.execute_script("window.scrollTo(0, 1800)")
sleep(3)
loadmore_skills=driver.find_element_by_xpath('//button[#class="pv-profile-section__card-action-bar pv-skills-section__additional-skills artdeco-container-card-action-bar artdeco-button artdeco-button--tertiary artdeco-button--3 artdeco-button--fluid"]')
actions = ActionChains(driver)
actions.move_to_element(loadmore_skills).perform()
#actions.move_to_element_with_offset(loadmore_skills, 0, 0).perform()
loadmore_skills.click()
Output
Update
In concerns to your newer problem, you need to implement a continuous scroll method that would enable you to dynamically update the skills section. This requires a lot of change and should ideally be asked as a another question.
I have also found a simple solution by setting the scroll to the correct threshold. For y=3200 seems to work fine for all the profiles I've checked including yours, mine and few others.
driver.execute_script("window.scrollTo(0, 3200)")
If the button is not visible on the page at the time of loading then use the until method to delay the execution
try:
myElem = WebDriverWait(browser, delay).until(EC.presence_of_element_located((By.ID, 'IdOfMyElement')))
print "Button is rdy!"
except TimeoutException:
print "Loading took too much time!"
Example is taken from here
To get the exact location of the element, you can use the following method to do so.
element = driver.find_element_by_id('some_id')
element.location_once_scrolled_into_view
This actually intends to return you the coordinates (x, y) of the element on-page, but also scroll down right to target element. You can then use the coordinates to make a click on the button. You can read more on that here.
You are getting NoSuchElementException error when the locators (i.e. id / xpath/name/class_name/css selectors etc) we mentioned in the selenium program code is unable to find the web element on the web page.
How to resolve NoSuchElementException:
Apply WebDriverWait : allow webdriver to wait for a specific time
Try catch block
so before performing action on webelement you need to take web element into view, I have removed unwated code and also avoided use of hardcoded waits as its not good practice to deal with synchronization issue. Also while clicking on show more button you have to scroll down otherwise it will not work.
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Chrome(executable_path="path of chromedriver.exe")
driver.get('https://www.linkedin.com/login?fromSignIn=true&trk=guest_homepage-basic_nav-header-signin')
driver.maximize_window()
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.NAME, "session_key"))).send_keys("email id")
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.NAME, "session_password"))).send_keys("password ")
WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//button[#class='btn__primary--large from__button--floating']"))).click()
driver.get("https://www.linkedin.com/in/kate-yun-yi-wang-054977127/?originalSubdomain=hk")
driver.maximize_window()
driver.execute_script("scroll(0, 250);")
buttonClick = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//span[text()='Show more']")))
ActionChains(driver).move_to_element(buttonClick).click().perform()
Output:
I am trying to create a bot which will fill up the signup forms for a particular website.
Website Details - http://hacknyu.org/signup
Code:
from selenium import webdriver
class HackNNYU(object):
first_name = 'input[ng-model="credentials.first_name"]'
last_name = 'input[ng-model="credentials.last_name"]'
email = '.col-sm-12>input[ng-model="credentials.email"]'
password = '.col-sm-12>input[ng-model="credentials.password"]'
agree_checkbox = '.ng-binding>input[ng-model="checkModel"]'
sign_up_button = 'div>button[type="submit"]'
accept_button = 'button[ng-click="positive()"]'
def fill_up_hack_nyu():
driver = webdriver.Firefox()
driver.get('http://hacknyu.org/signup')
driver.find_element_by_css_selector(HackNNYU.first_name).send_keys('Friday')
driver.find_element_by_css_selector(HackNNYU.last_name).send_keys('Night')
driver.execute_script("window.scrollTo(0, 300);")
driver.find_element_by_css_selector(HackNNYU.email).send_keys('ade347#gmail.edu')
driver.find_element_by_css_selector(HackNNYU.password).send_keys('123456')
driver.find_element_by_css_selector(HackNNYU.agree_checkbox).click()
driver.find_element_by_css_selector(HackNNYU.accept_button).click()
# driver.execute_script("window.scrollTo(0, 400);")
driver.find_element_by_css_selector(HackNNYU.sign_up_button).click()
fill_up_hack_nyu()
Problem
driver.find_element_by_css_selector(HackNNYU.sign_up_button).click()
The main problem is in this line. Manually when you click on signup button it is working fine but when I run this program, I can see it is clicking on signup button but nothing is happening after that. Could anyone help me why this is not working? I am just trying to register for an event using a bot. I will highly appreciate any help you can provide.
Error
Sometimes I always receive this error
selenium.common.exceptions.WebDriverException: Message: Element is not clickable at point (796.4000244140625, 45.399993896484375). Other element would receive the click
The page has a banner at the top which makes the automatic scrolling hide the submit button. To overcome this issue, you can define the scrolling behaviour to scroll at the bottom instead. Moreover it seems that your script is no correctly clicking on the checkbox that should display the terms popup.
Here is a working script to create a new account on hacknyu:
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# set the scrolling behavior to down
DesiredCapabilities.FIREFOX["elementScrollBehavior"] = 1
driver = webdriver.Firefox()
wait = WebDriverWait(driver, 10)
# load the page
driver.get("http://hacknyu.org/signup")
# get the form element
form = driver.find_element_by_css_selector("form[name='signupForm']")
# fill the fields
form.find_element_by_css_selector("input[name='firstName']").send_keys("myfirstname")
form.find_element_by_css_selector("input[name='lastName']").send_keys("mylastname")
form.find_element_by_css_selector("input[name='email']").send_keys("na#na.na")
form.find_element_by_css_selector("input[name='password']").send_keys("mypassword")
# click and accept terms
form.find_element_by_xpath("//input[#name='terms']/..").click()
wait.until(EC.presence_of_element_located((By.XPATH, "//button[.='Accept']"))).click()
wait.until_not(EC.presence_of_element_located((By.CSS_SELECTOR, ".modal")))
# click on submit
form.find_element_by_css_selector("button[type='submit']").click()
It is probably timing issue. You can use explicit wait to make sure the element is clickable
wait = WebDriverWait(driver, 10)
wait.until(expected_conditions.element_to_be_clickable((By.CSS_SELECTOR, HackNNYU.sign_up_button))).click()
This will wait up to 10 seconds for the button to be clickable before clicking on it.
Mostly providing wait or sleep before click will helps you simulate click correctly. Some situations click by using Actions also helps me. In Java
Actions moveAndClick=new Actions(driver);
moveAndClick.moveToElement(driver.findElement(By.cssSelector("HackNNYU.sign_up_button"))).click().build().perform();
and one more way is to use javascript executor.
WebElement element = driver.findElement(By.cssSelector("HackNNYU.sign_up_button"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
Thank You,
Murali
I am trying to click an element, for example "AH", in this page. I use the following code.
from selenium import webdriver
url = "http://www.oddsportal.com/soccer/brazil/serie-a/internacional-santos-vcGTTAKH/"
driver = webdriver.Firefox()
driver.get(url)
element_to_click = driver.find_element_by_link_text("AH")
element_to_click.click()
The problem is that after the element is clicked and the new page is loaded, it goes back to the first page.
Focus the element and call click_and_hold action (worked for me):
from selenium.webdriver import ActionChains
actions = ActionChains(driver)
actions.move_to_element(element_to_click).click_and_hold(element_to_click).perform()
alecxe , that works.
Just to add to the discussion here
So on mouse down it is invoking onClick for the uid(4), when we do a normal click on the element we do not realize that it worked on mouse down not on mouse click.
Thats why when we are using webdriver to do element.click() on it, this does not work and when we use Actions class to simulate mouse down using click_and_hold, It works !!