Selenium : switch to modal window handle gives error - python

I have this webpage https://account.proton.me/login?language=en where I am trying to switch to modal after logging in to the page. Please note that the modal appears even if you give wrong id and password, so to reproduce you can use the same code below
driver.get('https://account.proton.me/login?language=en')
usernameField = driver.find_element(By.XPATH,'//*[#id="username"]')
usernameField.send_keys("kuchbhirandom#some.thing")
passwordField = driver.find_element(By.XPATH,'//*[#id="password"]')
passwordField.send_keys("yehbhikuchbhi")
loginbutton = driver.find_element(By.XPATH,'//button[#type="submit"]')
loginbutton.click()
The above code gives us the modal
I ttried checking the window handles and switching to them one by one which gives me
driver.window_handles
['CDwindow-34B695696D2295F87F84F06321D10117', 'CDwindow-212C47AEC0CCD8240A4F9675D5B5BEF2', 'CDwindow-5A39DFE9B9C75CFA7316BF2098765D05', 'CDwindow-796B9EF6777039A036CCF7C3D452807A', 'CDwindow-1DF355426CF56902DC339955FF55C9AE', 'CDwindow-1B700B499C716086FA269E89B0ED3835']
for handle in driver.window_handles:
driver.switch_to.window(handle)
try:
checkbox = driver.find_element(By.XPATH,'//div[#id="checkbox"]')
print('found')
except:
pass
but I get the same error "No such element"
Talking about solving the captch : I have an external API that does it for me, but I need to click that check box here, but stuck in switching to the modal part
Note that : to reproduce issue you can use same code above, no need to create account.

Problem is that you have 2 nested iframes in the site,
You'll have to perform driver.switch_to.frame() for each of them:
# After pressing "sign-in"
captcha_iframe = driver.find_element(By.CSS_SELECTOR, '[title="Captcha"]')
driver.switch_to.frame(captcha_iframe)
inner_iframe = driver.find_element(By.CSS_SELECTOR, 'iframe')
driver.switch_to.frame(inner_iframe)
# Perform captcha check
driver.find_element(By.CSS_SELECTOR, '#checkbox').click()
Notice that after each switch_to, I directly use the new driver's context, and I do not perform a search under the element I found.

Related

Finding Valid Telegram Channel using selenium python

Hello good morning/evening! i want to ask, is there a way to differentiate this two type of way telling that those channels does not exist? I'm creating a tool to find existing channel on telegram. Here are the examples.
When i try to run my code, the channels that does not exist still counts as an existing channel.
Here is the code that use, to differentiate this 2 type of way telegram telling that the channel does not exist. I used the help of selenium and chrome driver to find the existing telegram channel.
for ss in cli1:
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=chrome_options)
driver.maximize_window()
driver.implicitly_wait(10)
driver.get(f"https://t.me/{ss}")
try:
if WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[2]/div[2]/div/div/div[1]/div[2]/a/div'))):
print(f'URL https://t.me/{ss} is not available')
Not_Exist.append(ss)
elif WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.XPATH, '/html/body/div[2]/div[2]/div/div[2]/a'))):
print(f'URL https://t.me/{ss} is not available')
Not_Exist.append(ss)
except:
print(f'URL https://t.me/{ss} is valid')
exists.append(ss)
driver.quit()
sleep(5)
Is there a way for a telegram channels that does not exist still say no available, instead of making the site available but it doesn't have any channel at all.Here are the link examples. Non existing site 1 https://t.me/minecraft Existing Site https://t.me/minecraftapkdownload Non Existing site 2https://telegram.org/
Thanks for the help!
In your code, in the try block, make the below changes
try:
if WebDriverWait(driver, 5).until(EC.presence_of_element_located((By.CSSSELECTOR, 'tgme_action_button_new shine'))):
print(f'URL https://t.me/{ss} is valid')
exists.append(ss)
except:
print(f'URL https://t.me/{ss} is not available')
Not_Exist.append(ss)
I would recommend you to use path made up of classnames/ids etc.
Paths like/html/body/div[2]/div[2]/div/div/div[1]/div[2]/a/div are prone to throw errors even with minimal changes to the GUI
In the above code, I have assumed that the View in Telegram button is shown if a channel is valid and for all other pages no such button is shown.
The class for the button is 'tgme_action_button_new shine'
The code checks if this button exists, if yes then it adds the page to the valid list, else to the invalid list

Python Selenium: Click Instagram next post button

I'm creating an Instagram bot but cannot figure out how to navigate to the next post.
Here is what I tried
#Attempt 1
next_button = driver.find_element_by_class_name('wpO6b ')
next_button.click()
#Attempt 2
_next = driver.find_element_by_class_name('coreSpriteRightPaginationArrow').click()
Neither of two worked and I get a NoSuchElementException or ElementClickInterceptedException . What corrections do I need to make here?
This is the button I'm trying to click(to get to the next post)
I have checked your class name coreSpriteRightPaginationArrow and i couldn't find any element with that exact class name. But I saw the class name partially. So it might help if you try with XPath contains as shown below.
//div[contains(#class,'coreSpriteRight')]
another xpath using class wpO6b. there are 10 elements with same class name so filtered using #aria-label='Next'
//button[#class='wpO6b ']//*[#aria-label='Next']
Try these and let me know if it works.
I have tried below code and it's clicking next button for 10 times
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
if __name__ == '__main__':
driver = webdriver.Chrome('/Users/yosuvaarulanthu/node_modules/chromedriver/lib/chromedriver/chromedriver') # Optional argument, if not specified will search path.
driver.maximize_window()
driver.implicitly_wait(15)
driver.get("https://www.instagram.com/instagram/");
time.sleep(2)
driver.find_element(By.XPATH,"//button[text()='Accept All']").click();
time.sleep(2)
#driver.find_element(By.XPATH,"//button[text()='Log in']").click();
driver.find_element(By.NAME,"username").send_keys('username')
driver.find_element(By.NAME,"password").send_keys('password')
driver.find_element(By.XPATH,"//div[text()='Log In']").click();
driver.find_element(By.XPATH,"//button[text()='Not now']").click();
driver.find_element(By.XPATH,"//button[text()='Not Now']").click();
#it open Instagram page and clicks 1st post and then it will click next post button for the specified range
driver.get("https://www.instagram.com/instagram/");
driver.find_element(By.XPATH,"//div[#class='v1Nh3 kIKUG _bz0w']").click();
for page in range(1,10):
driver.find_element(By.XPATH,"//button[#class='wpO6b ']//*[#aria-label='Next']" ).click();
time.sleep(2)
driver.quit()
As you can see, the next post right arrow button element locator is changing between the first post to other posts next page button.
In case of the first post you should use this locator:
//div[contains(#class,'coreSpriteRight')]
While for all the other posts you should use this locator
//a[contains(#class,'coreSpriteRight')]
The second element //a[contains(#class,'coreSpriteRight')] will also present on the first post page as well, however this element is not clickable there, it is enabled and can be clicked on non-first pages only.
As you can see on the picture below, the wp06b button is inside a lot of divs, in that case you might need to give Selenium that same path of divs to be able to access the button or give it a XPath.
It's not the most optimized but should work fine.
driver.find_element(By.XPATH("(.//*[normalize-space(text()) and normalize-space(.)='© 2022 Instagram from Meta'])[1]/following::*[name()='svg'][2]")).click()
Note that the XPath leads to a svg, so basically we are clicking on the svg element itself, not in the button.

How do I fill out an html form using selenium?

url = http://ptvtelecom.com/
If you follow the url and click the button which says 'combrobar' which should be visible in the middle of the screen, it takes you to a form that needs to be filled out. I was wondering how to fill out the form using selenium.
So ive already tried finding the element by id and by name but it does not work. Any help on how to find the element of the first text box for instance would be greatly aprreaciated.
option = webdriver.ChromeOptions()
option.add_argument(" — incognito")
browser =
webdriver.Chrome(executable_path='/Users/grsanchez/downloads/chromedriverM',
options=option)
browser.get('http://ptvtelecom.com/')
browser.find_element_by_xpath('//*
[#id="cobertura"]/div/div[2]/div/div/p/a').click()
Here is where it goes wrong
name = browser.find_element_by_id('nombre')
name.send_keys('user1')
read the comments in the code to understand why your code isn't working.
basically, you're trying to select something that exists inside an iframe.
option = webdriver.ChromeOptions()
option.add_argument("--incognito")
browser = webdriver.Chrome(executable_path='/Users/grsanchez/downloads/chromedriverM',
options=option)
browser.get('http://ptvtelecom.com/')
## finding the button that shows the form
btn = browser.find_element_by_css_selector('#cobertura .boton-cobertura')
## using js to click it, to avoid getting issues in case the button wasn't visible
driver.execute_script("arguments[0].click();", btn)
## the element you want to select is actually inside an iframe, so we need to switch to it, if we want to select anything
driver.switch_to.frame(driver.find_element_by_css_selector('#popmake-1432 iframe'));
## selecting the name input and sending a string
name = driver.find_element_by_css_selector('#nombre')
name.send_keys('user1')
PS to return to the main frame, you can do this :
driver.switch_to.default_content()
you need to switch to iframe something like driver.switchTo().frame("a077aa5e");
then use your locators inside the iframe

Selenium Hover/Click event on ajax filled menu options

Having serious issues here. Someone please help.
I am trying to login to a website. - This Works!
Redirect to the page I want after Login - This Works!
Now once in, I have to hover over the settings icon so the dropdown shows, and then click on the "Settings" options that has NO ID or CLASS or HREF.
Now there is a couple of reasons I cant do this. Number 1 is if I try to click on the link after the hover, it tells me that it's hidden and I cant interact with it. Also the menu options in the form are populated and appended once you hover, through ajax I think. They are not on the initial page load.
wait = WebDriverWait(driver, 10)
box = wait.until(EC.visibility_of_element_located((By.ID, "yucs-help_button")))
menuButton = driver.find_element_by_id("yucs-help_button")
ActionChains(driver).move_to_element(menuButton).perform()
After the above code is deployed I print the driver.page_source and can see (below) that the new menu options are there, if you don't hover, the below code will not be on the page.
Now the <a> i'm trying to click is the <span>Settings</span> option, and for the life of me, it will not work. Either can't find it, not clickable, can't interact with it, etc, etc, etc. xpath, css_selector, partial_name, nothing finds this thing. Also whats weird is once you click on it, from a browser, it appends an ID to <span> So weird. Any ideas?
<a data-ylk="rspns:nav;t3:tl-lst;t5:custitm;slk:custitm;elm:itm;elmt:custitm;itc:0;cpos:2" class="C(#000)! Td(u):h " data-mad="options" data-customevt="true" href="#" data-rapid_p="18"><span>Settings</span></a>
To perform mouse over event on element you should try to use .execute_script() using following java script :-
wait = WebDriverWait(driver, 10)
box = wait.until(EC.visibility_of_element_located((By.ID, "yucs-help_button")))
menuButton = driver.find_element_by_id("yucs-help_button")
driver.execute_script("var clickEvent = document.createEvent('MouseEvents');clickEvent.initEvent('mouseover', true, true); arguments[0].dispatchEvent(clickEvent);", menuButton)
Now after successfully mouse over you should try to click on Settings link as below :-
driver.find_element_by_xpath("//span[contains(text(), 'Settings')]/parent::a[#data-mad = 'options']").click()
Hope it will help you..:)

Selenium driver doesn't click on element sometimes

currently i'm writing a web scraper that will work in infinite loop. It gets a page, searches for some buttons and clicks one of them. But sometimes it doesn't! I save a screenshot in case of some fail and it showed me that page didnt changed after button clicked.
driver.find_element_by_xpath('//input[#name = "btn"]').click()
time.sleep(3)
I have bypassed this with a loop checking does we see that element still.
while driver.find_elements_by_xpath('//input[#name = "Submit"]') != []:
driver.find_element_by_xpath('//input[#name = "Submit"]').click()
But hope to find a root cause of this. What it could be?
I also faced a similar problem with my application. Clicking the element through action class worked for me.
Here is the sample code in Java:
WebElement webElement = driver.findElement(By.id("Your ID Here"));
Actions builder = new Actions(driver);
builder.moveToElement(webElement).click(webElement);
builder.perform();
If clicking with action class does not work, you can also try clicking element by Javascript.
WebElement webElement = driver.findElement(By.id("Your ID here"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", webElement);

Categories