Use python and selenium to delete my comments in reddit - python

I am trying to write a script to delete all my comments on my profile in Reddit.
So I am currently using Selenium to log-in and try to delete my comments, however I am stuck at the point when after my script press delete on my comment and it changes to "Are you sure Yes/No" then it can't find the "Yes" element by Xpath. The following code throws the error:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.ElementNotVisibleException: Message:
Element is not currently visible and so may not be interacted with
Stacktrace:
My code is as follows:
del_button = driver.find_element_by_xpath("//*[contains(#id,'thing_"+delete_type+"')]//div[2]/ul/li[7]/form/span[1]/a")
del_button.click()
time.sleep(3)
yes_button = driver.find_element_by_xpath("//*[contains(#id,'thing_"+delete_type+"')]//div[2]/ul/li[7]/form/span[1]//a[1]")
yes_button.click()
time.sleep(3)

As there could be several hidden elements with same attributes on page, you might need to use index to click on exact element:
driver.find_elements_by_xpath('//a[#class="yes"]')‌​[N].clic‌​k() # N is the index of target link
I f you can't define exact index, you can use below code:
from selenium.common.exceptions import ElementNotVisibleException
for link in driver.find_elements_by_xpath('//a[#class="yes"]')‌:
try:
link.click()
break
except ElementNotVisibleException:
pass

Related

Python Selenium send_keys to email input field

I am trying to make an auto-checkout script on https://www.footish.se/sneakers/fila-wmns-disruptor-run-1010866-60m
I have made it to the checkout page, but unable to enter my email in the "email" input-field.
The code looks like this
email = driver.find_element_by_xpath("/html/body/div/span/div/div/div/div[1]/div/div/div[1]/div/form/div[2]/div[1]/div/label/div/div/input")
email.send_keys("test#email.com")
Have implemented some sort of function to wait for the desired elements untill they are loaded in. One example->
while not find:
try:
find = driver.find_element_by_xpath("/html/body/form/div[5]/div/div[4]/div[1]/div[1]/div[2]/div[1]/div[10]/div[1]/h2")
print("Loaded info")
except:
continue
The error i am getting is this.
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"/html/body/div/span/div/div/div/div[1]/div/div/div[1]/div/form/div[2]/div[1]/div/label/div/div/input"}
How would i resolve this? Thanks in advance....
It seems like the email field is a dynamicallly generated element and so when a check is initially made it is not yet present. You may try and use the until method to wait for a specific time and see if it indeed does get applied to the DOM.
Sample code
driver = webdriver.Chrome()
driver.get("url")
try:
element = WebDriverWait(driver, 10).until(
EC.visibility_of_element_located((By.ID, "myDynamicElement")) # set your id here
)
finally:
driver.quit()
Do update if it doesn't work. It's then likely to do with frame or wrong path issues.

Loop through find_element_by_name python selenium

I have a code where it looks for a name and I am trying to write an if statement that says if it can't find that name look for something else.
What I have so far is as follows:
excel = driver.find_element_by_name("Export to Excel")
if excel == None:
driver.implicitly_wait(15)
search = driver.find_element_by_xpath("//span[#id='inplaceSearchDiv_WPQ2_lsimgspan']")
search.click()
else:
excel.click()
I know what's inside the if statement works because I tested it out. Am I suppoed to change my argument in my if statement? The error I get is selenium.common.exceptions.NoSuchElementException: Message: No such element I tried entering "No such element" instead of "None" but I still get the same error. Also it tells me Exception Unhandled NoSuchElementException('No such element', None, None) can some give me advise on what I am doing wrong with the if statement? The error also say that it is found at excel = driver.find_element_by_name("Export to Excel") when the button isn't present in the page. When it is, it'll go straight to the else part of the statement
The find_element_by_name method on your driver will raise the NoSuchElementException exception if it cannot find the webelement.
Try this
from selenium.common.exceptions import NoSuchElementException
try:
excel = driver.find_element_by_name("Export to Excel")
excel.click()
except NoSuchElementException:
driver.implicitly_wait(15)
search = driver.find_element_by_xpath("//span[#id='inplaceSearchDiv_WPQ2_lsimgspan']")
search.click()

clicking slippery "ElementNotVisibleException" button selenium webdriver python

https://gist.github.com/codyc4321/724f05aca8f6775e2fc1
Hi, bitbucket changed their login page, and is giving me a hassle. Based on the following gist, using driver.click_button causes:
ElementNotVisibleException at /bitbucket/create-repo
Message: Element is not currently visible and so may not be interacted with
Stacktrace:
at fxdriver.preconditions.visible (file:///tmp/tmpSNzLIl/extensions/fxdriver#googlecode.com/components/command-processor.js:9981)
at DelayedCommand.prototype.checkPreconditions_ (file:///tmp/tmpSNzLIl/extensions/fxdriver#googlecode.com/components/command-processor.js:12517)
at DelayedCommand.prototype.executeInternal_/h (file:///tmp/tmpSNzLIl/extensions/fxdriver#googlecode.com/components/command-processor.js:12534)
at DelayedCommand.prototype.executeInternal_ (file:///tmp/tmpSNzLIl/extensions/fxdriver#googlecode.com/components/command-processor.js:12539)
at DelayedCommand.prototype.execute/< (file:///tmp/tmpSNzLIl/extensions/fxdriver#googlecode.com/components/command-processor.js:12481)
using driver.submit_form causes error in the browser itself:
using driver.activate_hidden_element causes:
ElementNotVisibleException at /bitbucket/create-repo
Message: Element is not currently visible and so may not be interacted with
activate_hidden_element failing really took the wind outta my sails for the last 5 minutes. How can I click this stonewalling button? Thank you
Okay, so the problem is actually in your locate_element method.
When you check for the xpath: "//button[normalize-space(text())='{text}']" it finds a button successfully but it is not the login button you are looking for. If you switch that with the input xpath: "//input[#value='{text}']" it finds the right input and successfully logs you in.
You should also remove the last two lines in the BitbucketDriver.login() method because the line self.click_button(search_text="Log in") throws an AttributeError.
Your locate_element method should look like this:
def locate_element(self, search_text, xpaths=None):
if not xpaths:
xpaths = [ "//input[#value='{text}']", "//button[normalize-space(text())='{text}']",
"//a[child::span[normalize-space(text())='{text}']]", "//a[normalize-space(text())='{text}']"]
try:
return self.driver.find_element_by_id(search_text)
except:
try:
return self.driver.find_element_by_name(search_text)
except:
try:
return self.driver.find_element_by_class_name(search_text)
except:
for path in xpaths:
try:
return self.driver.find_element_by_xpath(path.format(text=search_text))
except:
pass
return None

Python Selenium to select "menuitem" from "menubar"

I have a code that clicks a button on a web page, which pops up a menubar. I would like to select a menuitem from the choices that appear, and then click the menuitem (if possible); however, I'm at a roadblock.
Here is the relevant part of the code so far:
from selenium import webdriver
driver = webdriver.Chrome()
driver.get('URL')
Btn = driver.find_element_by_id('gwt-debug-BragBar-otherDropDown')
Btn.click() #this works just fine
MenuItem = driver.find_element_by_id('gwt-uid-463') #I'm stuck on this line
MenuItem.click()
Here is the error it's throwing, based on what I have written:
raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.NoSuchElementException: Message: no such element
Note: it appears that the id for this element changes each time the page loads (which is probably the cause of the error). I've tried searching for the element by find_element_by_class_name as well, but it has a compound class name and I keep getting an error there, too.
Here's the code of the menubar:
<div class="gux-combo gux-dropdown-c" role="menubar" id="gwt-debug-BragBar-otherMenu">
and the menuitem I want:
<div class="gux-combo-item gux-combo-item-has-child" id="gwt-uid-591" role="menuitem" aria-haspopup="true">text</div>
I'm looking for a way to select the menuitem. Thanks!
Try this xpath
driver.find_element_by_xpath('//div[#role='menuitem' and .='text']').click();
It will check for the 'div' element having attribute 'role' as 'menuitem' and having exact text as 'text'.
Say, there is a menuitem "Lamborghini AvenTaDor" under your menu. So, the code for that will become:
driver.find_element_by_xpath('//div[#role='menuitem' and .='Lamborghini AvenTaDor']').click();
You can find the element by xpath and check that the id attribute starts with gwt-uid-:
menu_item = driver.find_element_by_xpath('//div[starts-with(#id, "gwt-uid-")]')
menu_item.click()
You can also apply additional checks if needed, e.g. check role attribute as well:
driver.find_element_by_xpath('//div[starts-with(#id, "gwt-uid-") and #role="menuitem"]')

How to use find_element_by_link_text() properly to not raise NoSuchElementException?

I have a HTML code like this:
<div class="links nopreview"><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://REFLECTION/INSTANCE/_CS_Data/null">Home</a></span> • <span><span><a class="csiAction"
href="/WebAccess/home.html#URL=centric://SITEADMIN/_CS_Site">Setup</a></span> • </span><span><a
title="Sign Out" class="csiAction csiActionLink">Sign Out</a></span></div>
I would like to click on the link that has the text Home. As this Home link appears after login, I have a code like this:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import re
browser = webdriver.Firefox() # Get local session of firefox
browser.get("http://myServer/WebAccess/login.html") # Load App page
elem = browser.find_element_by_name("LoginID") # Find the Login box
elem.send_keys("Administrator")
elem = browser.find_element_by_name("Password") # Find the Password box
elem.send_keys("Administrator" + Keys.RETURN)
#try:
elem = browser.find_element_by_link_text("Home")
elem.click()
The part till login works great. However the last but one line is problematic
elem = browser.find_element_by_link_text("Home")
It raises this NoSuchElementException where the Home link is there as you can see from the HTML code.
raise exception_class(message, screen, stacktrace)
NoSuchElementException: Message: u'Unable to locate element: {"method":"link text","selector":"Home"}'
Any guidance as to what I am doing wrong, please?
Have you tried adding an implicit wait to this so that it waits instead of running to quickly.
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import re
browser = webdriver.Firefox() # Get local session of firefox
browser.implicitly_wait(10) #wait 10 seconds when doing a find_element before carrying on
browser.get("http://myServer/WebAccess/login.html") # Load App page
elem = browser.find_element_by_name("LoginID") # Find the Login box
elem.send_keys("Administrator")
elem = browser.find_element_by_name("Password") # Find the Password box
elem.send_keys("Administrator" + Keys.RETURN)
#try:
elem = browser.find_element_by_link_text("Home")
elem.click()
The implicitly_wait call makes the browser poll until the item is on the page and visible to be interacted with.
The most common issues with NoSuchElementException while the element is there are:
the element is in different window/frame, so you've to switch to it first,
your page is not loaded or your method of page load is not reliable.
Solution could include:
check if you're using the right frame/window by: driver.window_handles,
write a wait wrapper to wait for an element to appear,
try XPath instead, like: driver.find_element_by_xpath(u'//a[text()="Foo"]').click(),
use pdb to diagnose your problem more efficiently.
See also: How to find_element_by_link_text while having: NoSuchElement Exception?
Maybe the element you are looking for doesn't exactly match that text string?
I know it can be tricky if it looks like it does on-screen, but sometimes there are oddities embedded like this simple markup "Home" or "Home" which makes the first char italic:
"<i>H</i>ome" is visually identical to "<em>H</em>ome" but does not match text.
Edit: after writing the above answer, I studied the question closer and discovered the HTML sample does show "Home" in plain text, but was not visible due to long lines not wrapping. So I edited the OP to wrap the line for readability.
New observation: I noticed that the Logout element has a "title" attribute, but the Home link element lacks such--try giving it one and using that.
Try adding an implicit wait to this in order to wait, instead of running too quickly.
Or
else you can import time and use time.sleep(25)

Categories

Resources