No such element error while clicking on Tinder Log in button - python

I'm trying to learn how to interact with the internet with python, and followed a tutorial I found on how to make a bot that interacts with tinder. I am able to get a chrome window up, and it can go to the website, but I run into issues when I try to click the login button. Here is the code I used(I imported webdriver from selenium, and sleep from time, but it wouldn't transfer here):
class tinderAI():
def __init__(self):
self.driver = webdriver.Chrome()
def login(self):
self.driver.get('https://tinder.com')
sleep(2)
fb_btn = self.driver.find_element_by_xpath('//*[#id="modal-manager"]/div/div/div/div/div[3]/div[2]/button')
fb_btn.click()
The error code I get after using this code is:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="modal-manager"]/div/div/div/div/div[3]/div[2]/button"}
Any help in resolving the issue would be appreciated. Thanks!

As per your code trials the locator:
//*[#id="modal-manager"]/div/div/div/div/div[3]/div[2]/button
represents the button with text as Log in with Facebook and to invoke click() on the element you need to induce WebDriverWait for the element_to_be_clickable() reaching till the child <span> and you can use either of the following Locator Strategies:
Using CSS_SELECTOR:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[type = 'button'][aria-label = 'Log in with Facebook'] span"))).click()
Using XPATH:
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//button[#type = 'button' and #aria-label = 'Log in with Facebook']//span"))).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:
Reference
You can find a detailed relevant discussion in:
Selenium “selenium.common.exceptions.NoSuchElementException” when using Chrome

Related

Selenium selenium.common.exceptions.NoSuchElementException error sending text to an element within iframe

im new to python and recently got into selenium , i made small projects for linkedin or twitter with it from a tutorial but now i wanted to do smth for my work(finance) and my problem is:
On this website: https://mfinante.gov.ro/domenii/informatii-contribuabili/persoane-juridice/info-pj-selectie-dupa-cui
When i try to find a element by any selector(name xpath css selectors etc) it tells me there is no such element
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
import time
from selenium.common.exceptions import NoSuchElementException
URL = 'https://mfinante.gov.ro/domenii/informatii-contribuabili/persoane-juridice/info-pj-selectie-dupa-cui'
s = Service('My chromedriver path')
driver = webdriver.Chrome(service = s)
driver.get(URL)
driver.maximize_window()
time.sleep(3)
cui_entry = driver.find_element(By.CSS_SELECTOR,'.col-sm-4 p input')
cui_entry.send_keys('23484xxx')
What i want it to do is to write this code where it says Introduceti codul unic de identificare (numeric): but it seems like im doing something wrong
To send a character sequence to the Enter the unique identification code (numeric) field as the elements are within an iframe so you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable.
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get("https://mfinante.gov.ro/domenii/informatii-contribuabili/persoane-juridice/info-pj-selectie-dupa-cui")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#_com_liferay_iframe_web_portlet_IFramePortlet_INSTANCE_AAFALwmoH3eD_iframe")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input[name='cod']"))).send_keys("23484")
Using XPATH:
driver.get("https://mfinante.gov.ro/domenii/informatii-contribuabili/persoane-juridice/info-pj-selectie-dupa-cui")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#id='_com_liferay_iframe_web_portlet_IFramePortlet_INSTANCE_AAFALwmoH3eD_iframe']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//input[#name='cod']"))).send_keys("23484")
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:
Reference
You can find a couple of relevant discussions in:
Switch to an iframe through Selenium and python
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

Python and Selenium: Locating and clicking a button for cookies within an iframe

Anybody has a solution to locate a button in webpage with an overlayed popup window like in the following example:
from selenium import webdriver
driver = webdriver.Firefox(executable_path=r'./geckodriver')
driver.get("https://www.academics.de/")
#after waiting for a while the popup window comes up
driver.find_elements_by_xpath("//*[contains(text(), 'Zustimmen')]")
The returned list is empty. Running the following
driver.find_element_by_css_selector(".button-accept")
results in:
NoSuchElementException: Message: Unable to locate element: .button-accept
The element with the text as E-Mail Login is within an iframe so you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable.
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get("https://www.academics.de/")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[title='SP Consent Message']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[title='Zustimmen']"))).click()
Using XPATH:
driver.get("https://www.academics.de/")
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//iframe[#title='SP Consent Message']")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[#title='Zustimmen']"))).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 couple of relevant discussions in:
Switch to an iframe through Selenium and python
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
An easy workaround to your problem would be to use uBlock Origin extension + Fanboy's Annoyances blocklist on your Selenium instance so that these annoying cookies messages would outright never appear. A way of enabling extensions is described in this StackOverflow answer:
Create a new firefox profile via right click windows start button >
run > firefox.exe -P
Then add whatever extensions you want, ublock, adblock plus etc
Call your profile folder with
profile = selenium.webdriver.FirefoxProfile("C:/test")
browser = selenium.webdriver.Firefox(firefox_profile=profile, options=ops)

Click on ember.js enabled element using Selenium

I am trying to click on the following button on a linkedin page using selenium:
<button id="ember607" class="share-actions__primary-action artdeco-button artdeco-button--2 artdeco-button--primary ember-view" data-control-name="share.post"><!---->
<span class="artdeco-button__text">
Post
</span></button>
I have tried to use:
driver.find_element_by_id, but the id of the button seems to keep changing number
driver.find_element_by_xpath, but this contains the button number, so also fails
driver.find_element_by_class_name('share-actions__primary-action artdeco-button artdeco-button--2 artdeco-button--primary ember-view'), this fails even though the class name is correct ?
Basically, all methods generate the same error message:
Exception has occurred: NoSuchElementException
Message: no such element: Unable to locate element:{[*the_error_is_here*]}
I have also tried the xpath contains() method, but this does not find the button.
What would be the correct way to click on this button please ?
I am using python version 3.9 on windows with driver = webdriver.Chrome
The element is an Ember.js enabled element. So to click() on the element with text as Post you can use either of the following Locator Strategies:
Using css_selector:
driver.find_element_by_css_selector("button.share-actions__primary-action[data-control-name='share.post']>span.artdeco-button__text").click()
Using xpath:
driver.find_element_by_xpath("//button[contains(#class, 'share-actions__primary-action') and #data-control-name='share.post']/span[#class='artdeco-button__text' and contains(., 'Post')]").click()
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:
Using CSS_SELECTOR:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.share-actions__primary-action[data-control-name='share.post']>span.artdeco-button__text"))).click()
Using XPATH:
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[contains(#class, 'share-actions__primary-action') and #data-control-name='share.post']/span[contains(., 'Post')]"))).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 detailed discussions in:
Selenium - Finding element based on ember
Automate Ember.js application using Selenium when object properties are changed at run-time
Ember: Best practices with Selenium to make integration tests in browser
Ember dropdown selenium xpath
Sometimes there are problems with buttons that are not clickable at the moment.
Try this:
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
wait = WebDriverWait(driver, 10)
button = wait.until(EC.element_to_be_clickable((By.XPATH, '[YOUR X_PATH TO THE BUTTON]')))
driver.execute_script("arguments[0].click()", button)
It's not the cleanest way to click any Button with selenium, but for me this method works mostly everytime.
//button[#class="share-actions__primary-action artdeco-button artdeco-button--2 artdeco-button--primary ember-view"].
Or
//button[contains(#id,'ember')]
Find the span with Post and click it's button tag.
//span[contains(text(), 'Post')]/parent::button
By xpath this should work:
//button/span[contains(text(), "Post")]
Combine it with a wait for the element:
button = WebDriverWait(driver, 10).until(
EC.element_to_be_clickable((By.XPATH, "//button/span[contains(text(), "Post")]"))
)
The problem with your by class selectors is the multiple class names. See this question: How to get elements with multiple classes for more details on how to overcome that.

Unable to type within username field within ProtonMail signup page using Selenium and Python

Hi I was trying to type the username field using Selenium and Python for the website https://mail.protonmail.com/create/new?language=en.
From the developer tool, I am able to inspect the item using CSSSelector/Xpath or other way. But when I am running the pthon script its not working. Screenshot attached:
My code is like the following:
BASE_URL = 'https://mail.protonmail.com/create/new?language=en'
driver = webdriver.Chrome(executable_path='./drivers/chromedriver')
driver.get(BASE_URL)
river.find_element_by_xpath('//*[#id="username"]').send_keys('someStringValue')
And after executing the following code, geetting the error:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="username"]"}
(Session info: chrome=83.0.4103.97)
Any suggestion?
The Email Address field is within an <iframe> so you have to:
Induce WebDriverWait for the desired frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable.
You can use either of the following Locator Strategies:
Using CSS_SELECTOR:
driver.get('https://mail.protonmail.com/create/new?language=en')
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"div.usernameWrap iframe[title='Registration form']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input.input#username"))).send_keys("FunnyBoss")
Using XPATH:
driver.get("https://mail.protonmail.com/create/new?language=en")
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//div[#class='usernameWrap']//iframe[#title='Registration form']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, "//input[#class='input' and #id='username']"))).send_keys("FunnyBoss")
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:
Reference
You can find a relevant discussion in:
Ways to deal with #document under iframe
Switch to an iframe through Selenium and python
Your xpath is OK, but the forms are inside an iframe.
So you need to switch to the iframe first:
driver.switchTo().frame(n);
Edit: If you read the TOS, you will see
This Service is provided exclusively to persons. Accounts registered by “bots” or automated methods are not authorized and will be terminated.

Selenium driver can't find any element after logging into a website [Python]

First of all if a similar topic occurred earlier I'm sorry but I couldn't find any problem like mine.
I would like to create a simple script which enters an e-mail website, log into my account and finds the amount of unread messages.
This is the part with logging in
from selenium import webdriver
from time import sleep
class sMailBot():
def __init__(self):
self.driver = webdriver.Chrome()
def login(self):
self.driver.get('website.com')
sleep(2)
btn_login = self.driver.find_element_by_xpath('//*[#id="username"]')
btn_login.send_keys('my_username')
btn_password = self.driver.find_element_by_xpath('//*[#id="password"]')
btn_password.send_keys('my_password')
btn_logintoaccount = self.driver.find_element_by_xpath('//*[#id="button"]')
btn_logintoaccount.click()
sleep(5)
It works really well. After logging into my mail account comments like driver.title or driver.current_url work.
Now I would like to scrape this part of html code:
<b>some_important_string_which_stores_the_amount_of_unread_mails</b>
I tried to do this using it's path
driver.find_element_by_xpath('//*[#id="MS_act1"]/span)
However it does not work. Moreover I can't find any other elements from this side.
I would like to highlight that I waiting even more than 10 seconds for the page to load.
The error which occurred
NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//*[#id="MS_act1"]/span/b"}
(Session info: chrome=80.0.3987.87)
As you asked I add some surrounding HTML code
<span style="float: right">
<b>some_important_string_which_stores_the_amount_of_unread_mails</b>
</span>
Please, don't use sleep, it's not a good choice for selenium.
Instead, use selenium waits:
driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 10).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit()
https://selenium-python.readthedocs.io/waits.html
First of all I will avoid using sleep. You may try using WebDriverWait instead. This will pause the browser until a given condition is satisfied.
e.g. as follows
WebDriverWait(self.driver, 60).until(EC.presence_of_element_located((By.XPATH, "//button[text()='Login']")))
This will wait for 60 sec maximum for the element (button with text Login) to occur in the page.
After logging into your mail account commands like driver.title and driver.current_url works but they are not part of the DOM Tree.
The relevant HTML would have helped us to construct a canonical answer. However to extract the desired text, you have to induce WebDriverWait for the visibility_of_element_located() and you can use either of the following Locator Strategies:
Using CSS_SELECTOR and get_attribute("innerHTML"):
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.CSS_SELECTOR, "[id^='MS_act'] span>b"))).get_attribute("innerHTML"))
Using XPATH and text attribute:
print(WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, "//*[starts-with(#id, 'MS_act')]//span/b"))).text)
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

Categories