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
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")
I have been writing a simple code for a 5 days now which I am doing to improve my knowledge on web scraping using different packages, I have already wrote one that downloads all the URL's and has the choice of downloading all images or videos but when I visited 'https://www.pixwox.com/' it has a different html design where the urls are hidden so I googled and started using Selenium. It was all going well until I hit a wall and the limits of my python knowledge.
The error below is what I have been getting for about 4 of them days, sometimes the code will work fine and others it will show the error below:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <a class="downbtn" href="https://scontent-frt3-2.cdninstagram.com/v/t51.2885-15/313202955_1363105014229232_3490221399588911023_n.jpg?stp=dst-jpg_e35_p828x828&_nc_ht=scontent-frt3-2.cdninstagram.com&_nc_cat=108&_nc_ohc=cB6igIdJd0UAX-sHSgL&edm=ACWDqb8BAAAA&ccb=7-5&ig_cache_key=Mjk2MDU4OTQ5NjY4NTI4NzQwMQ%3D%3D.2-ccb7-5&oh=00_AfAL1tPs2in8qcStQLZMdlDGZxdNRp5H5nnV4LpHWR07gg&oe=6363A260&_nc_sid=1527a3&dl=1">...</a> is not clickable at point (156, 814). Other element would receive the click: <iframe id="h12_frm_bl9ib7ijd9k" scrolling="no" frameborder="0" width="100%" height="auto" marginheight="0" marginwidth="0" style="margin: 0px; padding: 0px; width: 100%; height: 84.6186px; overflow: hidden;"></iframe>
(Session info: chrome=106.0.5249.119)
I know this means that the element I'm trying to click on has another element currently over top of it but currently even with stepping through the code I have not been able to see what is covering the element.
View more
My code is below, Please excuse the code for being messy, I am still learning.
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
option = webdriver.ChromeOptions()
option.add_argument(" — incognito")
#option.add_argument("start-maximized")
#option.add_argument("--window-size=1400,600")
user = input("User: ")
full_url = 'https://www.pixwox.com/profile/' + user + '/'
driver = webdriver.Chrome()
driver.get(full_url)
print(driver.title)
i = 0
while i < int(12):
driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")
i += 1
time.sleep(2)
download_button = "downbtn"
WebDriverWait(driver, 10).until(ec.presence_of_element_located((By.CLASS_NAME, download_button)))#.click()
elements = driver.find_elements(By.CLASS_NAME, download_button)
time.sleep(5)
for element in elements:
if element.text == 'Download': element.click()##### Added this sleep time ? time.sleep(2)
print(f"Dowdloading: {element}")
time.sleep(5)
else:
pass
also I know compared to other peoples code this is quite basic but I am still learning so any help would be great to further my learning, please excuse the while loop, I didn't know how else to keep scrolling down without using it.
Fix's tried:
Tried extending the sleep time to see whether it is a loading issue.
Tried to scroll down to see if that was causing the issue but that raises another issue ie the view more button which is another obstacle.
Stepped through the code using Thonny but was not able to find what is intercepting the element.
Tried https://stackoverflow.com/questions/44724185/element-myelement-is-not-clickable-at-point-x-y-other-element-would-receiv
Tried https://stackoverflow.com/questions/62260511/org-openqa-selenium-elementclickinterceptedexception-element-click-intercepted
I was expecting my code to be able to take a user input and download all images and videos on the whole page, currently it is very intermittent 99% of the time it downloads one image and then raises an 'ElementClickInterceptedException' error, that 1% downloads roughly 50 images and videos before raising the same error. I was also expecting it to scroll to the very bottom of the page so all images/videos load but the
View more
button stops the code from continuing.
Any help would be greatly appreciated.
Thank you
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 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 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 :)