Why does firefox keep getting hungup after the fourth run through - python-3.x

I am trying to create a bot that clicks on a link on my site, opens a tab, closes, and then continues the cycle.
This keeps getting hungup after the 4-5 cycle however.
I also cannot figure out how to simply close both of the tabs, and get the url again as to not have to quit.
Sorry if this is very basic, I am new to this. :)
I am using selenium, firefox webdriver
from time import sleep
from selenium import webdriver
from keyboard import press
while True:
browser = webdriver.Firefox()
browser.implicitly_wait(10)
browser.get('https://pridedogecoin.com/')
sleep(15)
login_link = browser.find_element_by_xpath('//*[#id="slider-6-slide-6-layer-13"]')
login_link.click()
sleep(5)
browser.quit()
sleep(15)

okay, you need to switch to first tab like below, also you should use close not quit, since close is meant to kill current window instance, where as quit will kill all of the browser instance :
import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.action_chains import ActionChains
driver = webdriver.Firefox(executable_path = "D:\geckodriver.exe")
driver.maximize_window()
while True:
driver.refresh()
time.sleep(10)
driver.get("https://pridedogecoin.com/")
driver.implicitly_wait(60)
wait = WebDriverWait(driver, 30)
current_windows_handle = driver.current_window_handle
wait.until(EC.element_to_be_clickable((By.ID, "slider-6-slide-6-layer-13"))).click()
driver.switch_to.window(driver.window_handles[1])
time.sleep(5)
driver.close()
driver.switch_to.window(current_windows_handle)

Related

How to deal with Chrome alerts with Selenium (Python)

I am very new to Selenium and am trying to automate sending messages through WhatsApp Web through Google Chrome. I am using a different api which lets users write messages directly to the phone number specified: https://wa.me/. However, there is an alert box which pops up and my code is unable to accept it.
Alert box screenshot
I have tried
driver.switch_to_alert().accept()
but this is resulted in a deprecation warning, so switched to:
alert_box = driver.switch_to.alert
alert_box.accept()
Both result in the following error:
Exception has occurred: NoAlertPresentException
Message: no such alert
(Session info: chrome=105.0.5195.102)
File "<hidden>", line 30, in <module>
driver.switch_to.alert.accept()
Current code:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
# Ensure you are logged in to whatsapp web
num = "xxxxxxxxxxxxxxxxxxxxx" # hid the number
driver.get("https://wa.me/" + num)
# Allow time to load page
driver.implicitly_wait(3)
# Switch to alert window to accept the alert to open URL
driver.switch_to.alert.accept()
driver.find_element(By.XPATH, './/a[#class="_9vcv _advm _9scb"][#id="action-button"][#title="Share on WhatsApp"]').click()
# Switch to alert window to accept the alert to open URL
driver.switch_to_alert().accept()
driver.find_element(By.XPATH, '//*[#id="fallback_block"]/div/div/h4[2]/a').click()
Interestingly, no alert shows up if I manually go through the screens myself.
Thanks in advance!
You probably should add some code to wait for the alert to open.
Have a look a the following snipped.
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
try:
wait = WebDriverWait(driver, 10)
wait.until(EC.alert_is_present(), 'waiting for alert')
alert = driver.switch_to.alert
alert.accept()
except TimeoutException:
print("timed out waiting for alert")

Cannot scroll all the way down the page, because it keeps refreshing Selenium Python

I am trying to automate saving website's description and url. I loop the program and come to the function get_info(). Basically it need to add the first website on the google page I load and scroll down so when it executes again it can add other websites. The problem is that the program refresh the page everytime it executes get_info() and brings you back at the top.
import selenium
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
import time
browser=webdriver.Firefox()
def get_info():
browser.switch_to.window(browser.window_handles[2])
description = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "h3"))
).text
site = WebDriverWait(browser, 10).until(
EC.presence_of_element_located((By.TAG_NAME, "cite"))
)
site.click()
url=browser.current_url
browser.back()
browser.execute_script("window.scrollBy(0,400)","")
To stop Chrome from auto-reloading , you can do this
driver.execute_cdp_cmd('Emulation.setScriptExecutionDisabled', {'value': True})
Link to read about this Chrome Devtools flag - here
The question already has been asked here

How find an specific element of page in Selenium python, because I can't find them

I have tried all ways that I knew, but can't found elements "login" and "password". Could someone help me, please? I am tired...
link: https://trading.finam.ru/
from selenium import webdriver
import traceback
from time import sleep
url = 'https://trading.finam.ru/'
driver = webdriver.Chrome(executable_path=r"C:\Users\Idensas\PycharmProjects\pythonProject\selenium\chromedriver.exe")
driver.get(url)
sleep(2)
try:
x = driver.find_element_by_xpath('//label[contains(text(),"Логин")]')
x.send_keys('123')
except Exception:
traceback.print_exc()
finally:
driver.close()
driver.quit()
The picture of that site
The following xpaths will work:
//input[#name='login']
//input[#name='password']
I see the site is loaded slowly so you must put some delay, preferably explicit wait there like:
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait.until(EC.visibility_of_element_located((By.XPATH, "//input[#name='login']")))
before trying to insert a texts there
Any website takes sometime to completely load and all the elements are visible to user.
To check the time take taken by your website in different regions you run a check on https://gtmetrix.com/
You can use the simple sleep for few secs until the page is loaded
from selenium import webdriver
import time
driver=webdriver.Chrome(//chromedriver_path_in_your_local//)
driver.get("https://trading.finam.ru/")
time.sleep(5)
login=driver.find_element_by_xpath("//input[#name='login']")
password=driver.find_element_by_xpath("//input[#name='password']")

Dealing with reCAPTCHA in Python Selenium

I need to automate a web page using python selenium, but it encounters a reCaptcha, which is in another frame. I want to solve the captcha, and continue the script by clicking the login button, when the reCaptcha has been solved; However, this gets tricky, since a frame is involved, and the frame needs to switch back to the default content. Can anyone help me in this regard?
from selenium import webdriver
from selenium.webdriver import ActionChains
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.support.ui import Select
import time
browser = webdriver.Chrome()
browser.delete_all_cookies()
browser.maximize_window()
browser.get("https://developer.syntecx.org/ptcl_ebills/signin.php")
browser.switch_to.frame(browser.find_element_by_tag_name("iframe"))
browser.find_element_by_xpath("//*[#id='recaptcha-anchor']/div[1]").click()
time.sleep(20)
browser.switch_to_default_content()
browser.find_element_by_xpath("//*[#id='login']/button").click()
Once you fill in the Email and Password field to click on the recaptcha you can use the following Locator Strategies:
Code Block:
options = webdriver.ChromeOptions()
options.add_argument("start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
driver = webdriver.Chrome(options=options, executable_path=r'C:\Utility\BrowserDrivers\chromedriver.exe')
driver.get("https://developer.syntecx.org/ptcl_ebills/signin.php")
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "input#email"))).send_keys("Asad_Ullah#stackoverflow.com")
driver.find_element_by_css_selector("input#password").send_keys("Asad_Ullah")
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[src^='https://www.google.com/recaptcha/api2/anchor?']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "span.recaptcha-checkbox.goog-inline-block.recaptcha-checkbox-unchecked.rc-anchor-checkbox"))).click()
driver.switch_to_default_content()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn.btn-primary.block.full-width.m-b"))).click()
Browser Snapshot:
Try do it:
Create a variable that get the main window:
mainWin = driver.current_window_handle
When u need to switch to main window:
driver.switch_to.window(mainWin)
Don't switch to the iframe.
Everything you need is in #g-recaptcha-response and [data-sitekey] which are both in main context.
You can simply wait for the checkbox to show the done icon and then the wait will be over
Like in the code below
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://somedomain/url_that_delays_loading")
try:
element = WebDriverWait(driver, 100).until(
EC.presence_of_element_located((By.ID, "myDynamicElement"))
)
finally:
driver.quit() here
Here I found a solution when you encounter a reCaptcha in a login page.
Simple approach that works very good for me. Check out for login button in a login page. If it lost it's existance, than you can proceed to the next stage. So, my solution does not require any timeout. Happy automating your stuff :)
def check_exists_by_xpath(xpath):
try:
self.driver.find_element_by_xpath(xpath)
except NoSuchElementException:
return False
return True
login_btn_xpath = 'your login button xpath'
while True:
print('You can solve recaptcha during this period and hit the login button.')
if check_exists_by_xpath(login_btn_xpath) is False:
break
# TODO: you can go along from here!

Selenium Python does not close the child window

I have webpage which open new browser window on click. I am able to get 2 handles however driver.close() always closes the first/main window.
from selenium import webdriver
import time
driver = webdriver.Chrome()
driver.get("file:///D:/blackhole/print.html")
han = driver.window_handles
print("handles:", han) # gets 1 handle
time.sleep(2)
click_btn = driver.find_element_by_link_text('Print')
click_btn.click()
han = driver.window_handles
print("handles:", han) # gets 2 handles
driver.switch_to_window = han[1] # first element is always first window handle
driver.close() # main window close
Below webpage code which invokes new window
<a href="print.html"
onclick="window.open('popprint.html',
'newwindow',
'width=300,height=250');
return false;"
>Print</a>
Same behaviour for Firefox as well.
Python 3.6.7
Selenium is unable to close the active window i.e the newly opened window because practically you havn't switched to the newly opened window in a clean way.
Solution
A few words about Tab/Window switching/handling:
switch_to_window(window_name) is deprecated for quite some time now and you need to use driver.switch_to.window
Always keep track of the Parent Window handle so you can traverse back later if required as per your usecase.
Always use WebDriverWait with expected_conditions as number_of_windows_to_be(num_windows) before switching between Tabs/Windows.
Always keep track of the Child Window handles so you can traverse whenever required.
Always use WebDriverWait with expected_conditions as title_contains("partial_page_title") before extracting the Page Title.
Here is your own code with some minor tweaks mentioned above:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox(executable_path=r'C:\WebDrivers\geckodriver.exe')
driver.get("file:///D:/blackhole/print.html")
parent_han = driver.window_handles
driver.find_element_by_link_text('Print').click()
WebDriverWait(driver, 10).until(EC.number_of_windows_to_be(2))
all_han = driver.window_handles
new_han = [x for x in all_han if x != parent_han][0]
driver.switch_to.window(new_han)
driver.close()
You can find a detailed discussion in Selenium Switch Tabs
driver.close() only closes the current window.
To close all Windows and quit the webdriver, call driver.quit() instead.

Resources