Selenium Alert Handling Python - python

So I am using Selenium to simply go to a given list of websites and take a screenshot of them. However I have run into some having alerts and some do not. I am looking to do something along the lines of if alert then this else keep moving.
Here is my current code
from selenium import webdriver
import pandas as pd
import time
path = "C:/Users/dge/Desktop/Database/NewPythonProject/html Grabber/Output/Pics/"
df = pd.DataFrame()
df = df.append(pd.read_csv('crime.csv'), ignore_index=True)
driver = webdriver.Chrome('C:/Users/dge/Desktop/Database/NewPythonProject/html Grabber/chromedriver.exe')
for i in df.index:
print(i)
pic = path + df['site'][i] + '.png'
driver.get('http://' + df['site'][i])
time.sleep(5)
driver.save_screenshot(pic)
I've seen this but just not sure how to add it in the loop
driver.find_element_by_id('').click()
alert = driver.switch_to_alert()
The best way to put this may be to say ignore any errors and continue on through my list of urls.

JavaScript can create alert(), confirm() or prompt()
To press button OK
driver.switch_to.alert.accept() # press OK
To press button CANCEL (which exists only in confirm() and prompt())
driver.switch_to.alert.dismiss() # press CANCEL
To put some text in prompt() before accepting it
prompt = driver.switch_to.alert
prompt.send_keys('foo bar')
prompt.accept()
There is no function to check if alert is displayed
but you can put it in try/except to catch error when there is no alert.
try:
driver.switch_to.alert.accept() # press OK
#driver.switch_to.alert.dismiss() # press CANCEL
except Exception as ex:
print('Exception:', ex)
Minimal working example.
Because I don't know page which displays alert so I use execute_script to display it.
from selenium import webdriver
import time
#driver = webdriver.Firefox()
driver = webdriver.Chrome()
driver.get('http://google.com')
# --- test when there is alert ---
driver.execute_script("console.log('alert: ' + alert('Hello World!'))")
#driver.execute_script("console.log('alert: ' + confirm('Hello World!'))")
#driver.execute_script("console.log('alert: ' + prompt('Hello World!'))")
time.sleep(2)
try:
driver.switch_to.alert.accept() # press OK
#driver.switch_to.alert.dismiss() # press CANCEL
except Exception as ex:
print('Exception:', ex)
# --- test when there is no alert ---
try:
driver.switch_to.alert.accept() # press OK
#driver.switch_to.alert.dismiss() # press CANCEL
except Exception as ex:
print('Exception:', ex)
# ---
driver.save_screenshot('image.png')
driver.close()
BTW: if you want to first try to press CANCEL and when it doesn't work then press OK
try:
driver.switch_to.alert.dismiss() # press CANCEL
except Exception as ex:
print('Exception:', ex)
try:
driver.switch_to.alert.accept() # press OK
except Exception as ex:
print('Exception:', ex)
BTW: different problem can be popup notifications or geolocation alerts
How to click Allow on Show Notifications popup using Selenium Webdriver

Related

Unable to select reCaptchaV2 checkbox in SeleniumBase

I have a SeleniumBase code like this
from seleniumbase import SB
from func_timeout import func_set_timeout, FunctionTimedOut
def checkbox():
print('- click checkbox')
checkbox = 'span#recaptcha-anchor'
try:
sb.wait_for_element(checkbox)
sb.click(checkbox)
sb.sleep(4)
except FunctionTimedOut as e:
print('- 👀 checkbox:', e)
When I call checkbox() it gives error and the browser crashes quickly without clicking the checkbox
I tried replacing
checkbox = 'id#recaptcha-anchor-label'
checkbox = 'id#rc-anchor-center-item'
but it didn't work
You might want to try avoiding the captcha altogether by running SeleniumBase in undetected-chromedriver mode (set uc=True, or run with --uc):
from seleniumbase import SB
with SB(uc=True) as sb:
sb.open("https://nowsecure.nl/#relax")
try:
sb.assert_text("OH YEAH, you passed!", "h1", timeout=7)
sb.post_message("Selenium wasn't detected!", duration=2)
print("\n Success! Website did not detect Selenium! ")
except Exception:
print("\n Sorry! Selenium was detected!")
If you still need to go through the captcha, then make sure that if you need to click something in an iframe, that you switch to the iframe first, such as with sb.switch_to_frame("iframe").
Also, the sb.click(selector) method will automatically wait for the element, which means that calling sb.wait_for_element(selector) before that is unnecessary.

Check if the browser opened with Selenium is still running (Python)

I want to check if a browser opened with Selenium is still open. I would need this check for closing a program. If the browser is not open, then the GUI should be destroyed without a message (tk.messagebox) coming. But if the browser is open, then the message should come as soon as the function is activated. Here is the function:
def close():
msg_box = tk.messagebox.askquestion('Exit Application', 'Are you sure you want to exit the application?',
icon='warning')
if msg_box == 'yes':
root.destroy()
try:
web.close()
except NameError:
sys.exit(1)
except InvalidSessionIdException:
sys.exit(1)
except WebDriverException:
sys.exit(1)
else:
return
I don't think there is a direct api for checking browser status. But you can use the the work around
def isBrowserAlive(driver):
try:
driver.current_url
# or driver.title
return True
except:
return False
Unfortunately, there's not a standardized way to check a driver's status.
Here's the most reliable cross-browser workaround that I've come up with over the years:
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import WebDriverException
def is_webdriver_alive(driver):
print('Checking whether the driver is alive')
try:
assert(driver.service.process.poll() == None) #Returns an int if dead and None if alive
driver.service.assert_process_still_running() #Throws a WebDriverException if dead
driver.find_element_by_tag_name('html') #Throws a NoSuchElementException if dead
print('The driver appears to be alive')
return True
except (NoSuchElementException, WebDriverException, AssertionError):
print('The driver appears to be dead')
return False
except Exception as ex:
print('Encountered an unexpected exception type ({}) while checking the driver status'.format(type(ex)))
return False
Usage:
driver_is_alive = is_webdriver_alive(driver)

How can I make this code execute the if statement properly

The below code is supposed to wait click a button after 2 seconds. after two clicks it should wait for 15 seconds before proceeding to click again. However the 15 second wait is not happening. What am I doing wrong?
#click follow
clicked=0
try:
Fclick=driver.find_element_by_xpath('//button[text()="Follow"]')
driver.execute_script("arguments[0].click();", Fclick)
time.sleep(1)
inputElement.send_keys(e)
except Exception:
driver.back()
time.sleep(2)
driver.get("https://www.instagram.com/am_batman33/?hl=en")
clicked +=1
if clicked == 2:
clicked = 0
time.sleep(15)
else:
time.sleep(2)
It seems indentation issue. if else condition falls under except block so until and unless if there is no exception in try block, the code won't execute.
Simple solution would be keep your code with same intend as try except block.
clicked=0
try:
Fclick=driver.find_element_by_xpath('//button[text()="Follow"]')
driver.execute_script("arguments[0].click();", Fclick)
time.sleep(1)
inputElement.send_keys(e)
except Exception:
driver.back()
time.sleep(2)
driver.get("https://www.instagram.com/am_batman33/?hl=en")
clicked +=1
if clicked == 2:
clicked = 0
time.sleep(15)
else:
time.sleep(2)

Open 2 Webdrivers at same time with multi-threading

I am working on Crawl project using Selenium and Webdriver. Since that data I need to crawl while big, I want to split it to 2 threads and run at the same time. But when I start 2 Webdrivers at the same time, my code can not recognize which driver belong to which thread to fill the information.
This is the code that I setup 2 threads run main function:
if __name__ == '__main__':
data = load_data(INPUT_DIR)
t1_data = data[:250]
t2_data = data[250:]
try:
_thread.start_new_thread(main, (t1_data, LOG_FILE_T1))
_thread.start_new_thread(main, (t2_data, LOG_FILE_T2))
except:
print ("Error: unable to start thread")
while 1:
pass
This code I start the Webdriver:
def start_driver():
global driver
options = Options()
options.add_argument("--disable-notification")
options.add_argument("--disable-infobars")
options.add_argument("--mute-audio")
#options.add_argument("headless")
driver = webdriver.Chrome(options=options)
Two Webdrivers after started, I will fill in the username/password
information on facebook.com
def login(email, password):
""" Logging into our own profile """
try:
driver.get('https://mbasic.facebook.com')
time.sleep(DELAY_TIME)
driver.find_element_by_name('email').send_keys(email)
driver.find_element_by_name('pass').send_keys(password)
driver.find_element_by_name('login').click()
# deal with "Not Now" button if it show off at first time
not_now_button = driver.find_element_by_xpath("//a")
if not_now_button.size != 0:
not_now_button.click()
except Exception as e:
print('Error in Login')
print(e)
exit()
At send_keys step, both threads fill in the same text box in 1 Webdriver.
How can I change my code for 2 threads can see different Webdrive and fill the info in ?
Just found out the solution, I want to share here if someone needed.
Instead of global driver, I will change to a local driver and pass it to each function.
def start_driver():
options = Options()
options.add_argument("--disable-notification")
options.add_argument("--disable-infobars")
options.add_argument("--mute-audio")
#options.add_argument("headless")
driver = webdriver.Chrome(options=options)
return driver
def login(driver, email, password):
""" Logging into our own profile """
try:
driver.get('https://mbasic.facebook.com')
time.sleep(DELAY_TIME)
driver.find_element_by_name('email').send_keys(email)
driver.find_element_by_name('pass').send_keys(password)
driver.find_element_by_name('login').click()
# deal with "Not Now" button if it show off at first time
not_now_button = driver.find_element_by_xpath("//a")
if not_now_button.size != 0:
not_now_button.click()
except Exception as e:
print('Error in Login')
print(e)
exit()
By this, 2 threads can see different Webdriver and fill their own information.

Python selenium script to continue running if element is not found

I am dealing with a pop up issue that seems to be random before I click on a button. I want to know if there is any way I can check if the element is displayed and click it, if it is not displayed, i want it to continue running the script. my current script keeps getting an error. when the pop up is displayed, my script runs PERFECT. my error takes place on my script at the
onetouch = self.driver.find_element _by_xpath("").
Here is a picture of my error:
self.driver.get(redirecturl)
self.driver.implicitly_wait(180)
login_frame = self.driver.find_element_by_name('injectedUl')
# switch to frame to access inputs
self.driver.switch_to.frame(login_frame)
# we now have access to the inputs
email = self.driver.find_element_by_id('email')
password = self.driver.find_element_by_id('password')
button = self.driver.find_element_by_id('btnLogin')
# input your email and password below
email.send_keys('')
password.send_keys('')
button.click()
#############
onetouch = self.driver.find_element_by_xpath(".//*[#id='memberReview']/div[2]/div/div/div[2]/div[1]/div[1]/a")
if onetouch.is_displayed():
time.sleep(2)
onetouch.click()
else:
print "onetouch not present....continuing script"
button2 = self.driver.find_element_by_id('confirmButtonTop')
button2.click()
button3 = self.driver.find_element_by_name('dwfrm_payment_paypal')
# if you want to test the program without placing an order, delete the button3.click() below this.........
button3.click
Actually find_element_by_xpath always returns either element or throws exception, So if there is no element by provided locator you can't execute is_displayed(). You should try using find_elements_by_xpath instead and check the length as below :-
onetouch = self.driver.find_elements_by_xpath(".//*[#id='memberReview']/div[2]/div/div/div[2]/div[1]/div[1]/a")
if len(onetouch) > 0:
time.sleep(2)
onetouch[0].click()
else:
print "onetouch not present....continuing script"
-------
Try following:
from selenium.common.exceptions import NoSuchElementException
try:
time.sleep(2)
self.driver.find_element_by_xpath(".//*[#id='memberReview']/div[2]/div/div/div[2]/div[1]/div[1]/a").click()
except NoSuchElementException:
print "onetouch not present....continuing script"

Categories