iframe name changes each time the page is reloaded - python

i'm having a problem with my script in pyhton. Each time when the web page that im using opens the iframe src changes.
By.CSS_SELECTOR,"iframe#IFRAME_muVN"
(For example de code above is the current iframe when i copy with css selector)
But when i enter to the web page again the name of that iframe changes.
#IFRAME_6Eh8
is there a way to manage that change of the iframe, because im allways getting timeout due to the webdriver wait and the iframe element is never gonna be found.
this is my code:
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from datetime import date
import time
s=Service(r'C:\Users\dbayona\Webdriver\chromedriver.exe')
driver = webdriver.Chrome(service = s)
driver.maximize_window()
driver.get('http://190.109.11.66:8888/BOE/BI')
iframe = driver.find_element(By.NAME, "servletBridgeIframe")
driver.switch_to.frame(iframe)
username = driver.find_element(By.XPATH, '//*[#id="_id0:logon:USERNAME"]')
username.send_keys("*****")
password = driver.find_element(By.XPATH, '//*[#id="_id0:logon:PASSWORD"]')
password.send_keys("*****")
login = driver.find_element(By.XPATH, '//*[#id="_id0:logon:logonButton"]')
login.click()
iframe =WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#iframeHome-122668")))
driver.implicitly_wait(15)
dropdown = driver.find_element(By.XPATH, '//*[#id="header3_5"]')
dropdown.click()
storesense = driver.find_element(By.XPATH, '//*[#id="li_item_0_4_1"]')
driver.implicitly_wait(5)
storesense.click()
iframe = WebDriverWait(driver, 120).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#IFRAME_muVN")))
date = driver.find_element(By.XPATH, '//*[#id="date-picker"]')
today = date.today()
d1 = today.strftime("%d/%m/%Y")
date.send_keys(d1)
driver.switch_to.default_content()
Code where im trying to find the iframe:
iframe = WebDriverWait(driver, 120).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe#IFRAME_muVN")))
image of the iframe:
Iframe of the page

Since the element is dynamic try the following css selector. ^ means startswith
iframe = WebDriverWait(driver, 120).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[id^='IFRAME_']")))

try to find by tag name <iframe> but make sure if you not have multiple tag name like this inside the element that its related to

Related

How to scrape Next button on Linkedin with Selenium using Python?

I am trying to scrape LinkedIn website using Selenium. I can't parse Next button. It resists as much as it can. I've spent a half of a day to adress this, but all in vain.
I tried absolutely various options, with text and so on. Only work with start ID but scrape other button.
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"xpath","selector":"//button[#aria-label='Далее']"}
This is quite common for this site:
//*[starts-with(#id,'e')]
My code:
from selenium import webdriver
from selenium.webdriver import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from time import sleep
chrome_driver_path = Service("E:\programming\chromedriver_win32\chromedriver.exe")
driver = webdriver.Chrome(service=chrome_driver_path)
url = "https://www.linkedin.com/feed/"
driver.get(url)
SEARCH_QUERY = "python developer"
LOGIN = "EMAIL"
PASSWORD = "PASSWORD"
sleep(10)
sign_in_link = driver.find_element(By.XPATH, '/html/body/div[1]/main/p[1]/a')
sign_in_link.click()
login_input = driver.find_element(By.XPATH, '//*[#id="username"]')
login_input.send_keys(LOGIN)
sleep(1)
password_input = driver.find_element(By.XPATH, '//*[#id="password"]')
password_input.send_keys(PASSWORD)
sleep(1)
enter_button = driver.find_element(By.XPATH, '//*[#id="organic-div"]/form/div[3]/button')
enter_button.click()
sleep(25)
lens_button = driver.find_element(By.XPATH, '//*[#id="global-nav-search"]/div/button')
lens_button.click()
sleep(5)
search_input = driver.find_element(By.XPATH, '//*[#id="global-nav-typeahead"]/input')
search_input.send_keys(SEARCH_QUERY)
search_input.send_keys(Keys.ENTER)
sleep(5)
people_button = driver.find_element(By.XPATH, '//*[#id="search-reusables__filters-bar"]/ul/li[1]/button')
people_button.click()
sleep(5)
page_button = driver.find_element(By.XPATH, "//button[#aria-label='Далее']")
page_button.click()
sleep(60)
Chrome inspection of button
Next Button
OK, there are several issues here:
The main problem why your code not worked is because the "next" pagination is initially even not created on the page until you scrolling the page, so I added the mechanism, to scroll the page until that button can be clicked.
it's not good to create locators based on local language texts.
You should use WebDriverWait expected_conditions explicit waits, not hardcoded pauses.
I used mixed locators types to show that sometimes it's better to use By.ID and sometimes By.XPATH etc.
the following code works:
import time
from selenium import webdriver
from selenium.webdriver import Keys
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
options = Options()
options.add_argument("start-maximized")
webdriver_service = Service('C:\webdrivers\chromedriver.exe')
driver = webdriver.Chrome(options=options, service=webdriver_service)
wait = WebDriverWait(driver, 10)
url = "https://www.linkedin.com/feed/"
driver.get(url)
wait.until(EC.element_to_be_clickable((By.XPATH, "//a[contains(#href,'login')]"))).click()
wait.until(EC.element_to_be_clickable((By.ID, "username"))).send_keys(my_email)
wait.until(EC.element_to_be_clickable((By.ID, "password"))).send_keys(my_password)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[type='submit']"))).click()
search_input = wait.until(EC.element_to_be_clickable((By.XPATH, "//input[contains(#class,'search-global')]")))
search_input.click()
search_input.send_keys("python developer" + Keys.ENTER)
wait.until(EC.element_to_be_clickable((By.XPATH, '//*[#id="search-reusables__filters-bar"]/ul/li[1]/button'))).click()
wait = WebDriverWait(driver, 4)
while True:
try:
next_btn = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "button.artdeco-pagination__button.artdeco-pagination__button--next")))
next_btn.location_once_scrolled_into_view
time.sleep(0.2)
next_btn.click()
break
except:
driver.execute_script("window.scrollBy(0, arguments[0]);", 600)

how can i open link in href with selenium python?

The link inside the href is constantly changing but the xpath of this href is always the same.
How can I click on the www.confirmationemail.com ?
<div dir="ltr">
<p>exampleTEXT.</p>
<p>www.confirmationemail.com</p>
<p>exampleTEXT.</p>
<p>exampleTEXT,</p>
<p>exampleTEXT</p>
</div>
This is the page I'm working on:https://www.minuteinbox.com/
The process is as follows: registering on a site with the e-mail received from here and receiving an e-mail, logging in to the e-mail, but I cannot click on the link in its content.
from selenium import webdriver
from time import sleep
import config2 as cf
from selenium.webdriver.support.select import Select
import selenium.webdriver.support.ui as ui
from selenium.webdriver.common.keys import Keys
from asyncio import sleep
import time
driver = webdriver.Chrome("C:\\ChromeDriver\\chromedriver.exe")
url = "https://www.minuteinbox.com/"
url2 = "EXAMPLE.COM"
driver.get(url)
element = driver.find_element_by_xpath("XPATH").text
print(element)
time.sleep(4)
driver.execute_script("window.open('');")
driver.switch_to.window(driver.window_handles[1])
driver.get(url2)
sec = driver.find_element_by_xpath("XPATH")
sec.click()
devam = driver.find_element_by_xpath("XPATH")
devam.click()
ad = driver.find_element_by_xpath("XPATH")
ad.send_keys("deneme")
soyad = driver.find_element_by_xpath("XPATH")
soyad.send_keys("test")
eMail = driver.find_element_by_css_selector("#user_email")
eMail.send_keys(element)
eMail2 = driver.find_element_by_css_selector("#user_email_confirmation")
eMail2.send_keys(element)
sifre = driver.find_element_by_css_selector("#user_password")
sifre.send_keys("PASS")
sifre2 = driver.find_element_by_css_selector("#user_password_confirmation")
sifre2.send_keys("PASS")
buton = driver.find_element_by_css_selector("SELECT")
buton.click()
hesapol = driver.find_element_by_css_selector("SELECT")
hesapol.click()
sleep(2)
driver.switch_to.window(driver.window_handles[0])
time.sleep(7)
bas = driver.find_element_by_css_selector("#schranka > tr:nth-child(1)")
bas.click()
time.sleep(1)
time.sleep(1)
SD = driver.switch_to.frame(driver.find_element_by_css_selector("iframe#iframeMail"))
time.sleep(5)
SD = driver.find_element_by_xpath("//a[contains(#href,'minuteinbox')]").click
driver.switch_to.default_content()
sd = I put this just to be able to write it in the code section
SOLVED
İMPORTS
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
bas = driver.find_element_by_css_selector("#schranka > tr:nth-child(1)")
bas.click()
time.sleep(3)
wait = WebDriverWait(driver, 10)
wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[id='iframeMail']")))
print(driver.page_source)
link = driver.find_element_by_xpath("/html/body/div/p[2]/a")
link.click()
As you mentioned, the XPath of that element is constant.
So you can get that element based the constant XPath locator and click it.
Something like this:
driver.find_element_by_xpath('the_constant_xpath').click()
UPD
The element you want to be clicked can be located by XPath.
However, it is inside an iframe, so in order to access it you will have to switch to that iframe first.
I have also made your locators better.
So your code could be something like this:
driver.switch_to.window(driver.window_handles[0])
time.sleep(5)
bas = driver.find_element_by_css_selector("td.from")
bas.click()
time.sleep(1)
driver.switch_to.frame(driver.find_element_by_css_selector("iframe#iframeMail"))
driver.find_element_by_xpath("//a[contains(#href,'minuteinbox')]").click
When you finished working inside the iframe you will have to get out to the default content with
driver.switch_to.default_content()

python selenium - Cant find the element of sign in button

I'm trying to create an automation test in Asos (for practice purpose only) however I'm having a hard time locating this sign-in element...
I need to click on that sign-in button.
these are the element I got in inspect:
a class="_1336dMe _1uUU2Co _1336dMe _1uUU2Co" href="https://my.asos.com/my-account?
lang=en-GB&store=COM&country=GB&keyStoreDataversion=3pmn72e-27"
data-testid="signin-link" tabindex="-1">Sign In
I had the same problem when trying to find this button on Google Maps. Is the sign in button on a pop up window? Then the problem is becuse you have to change between frames.
Here is a code sample:
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome('driver path')
url = 'url'
driver.get(url)
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, '//*[#id="consent-bump"]/div/div[1]/iframe')))
agree = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="introAgreeButton"]/span/span')))
agree.click()
#back to the main page
driver.switch_to_default_content()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="searchboxinput"]'))).send_keys('gostilne')
search = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="searchbox-searchbutton"]')))
search.click()
Make shure that the xpath for frames and buttons is correct.

Selenium - getting audio src from html using python

I am trying to use selenium to get a particular attribute from recaptcha audio-source.
however, i'm unsure of how to do so. Here is an example from https://www.google.com/recaptcha/api2/demo
Click on "I am not a robot"
Select the headphone
Extract the src link
<audio id="audio-source" src="https://www.google.com:443/recaptcha/api2/payload?p=06AGdBq278w_OvG1dn_-_sgoVrqxLWcBq0IBkj2htJcsS-iTT3HtmwlhcTfBrcbQelxGI0hiep-082RypK_wZUTE-XzVbmcJ8zANM9l5O_0ka3x_7E_Hf_-vGqcRHCdRO7w2krqcgZDJSu1wj5wVyWhbDGITl55YsOs21NoX4aHk38173DPPu-Kj6T3mnqnA_3rMsdTkOUtMyl&k=6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-" style="display: none"></audio>
I want to retrieve the src link and print it out
may I know if there is any ways for me to use selenium to do so?
My code so far allows me to load into recaptcha demo page -> Click on I am not a bot -> click on the audio button
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
import time
PATH="C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("http://localhost/recaptcha-v2/")
# driver.get("https://www.google.com/recaptcha/api2/demo")
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-anchor"))).click()
driver.switch_to.default_content()
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR,"iframe[title='recaptcha challenge']")))
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button#recaptcha-audio-button"))).click()
#This works, i can get the captcha token
# Src_URL = driver.find_element_by_id('recaptcha-token').get_attribute('value')
#This does not work, it can't locate the src
WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "audio-source")))
Src_URL = driver.find_element_by_id('audio-source').get_attribute('src')
print(Src_URL)
Please advise thank you!
I have used the below code to extract src attribute from the audio tag (Change iframe if the audio tag is in another iframe) -
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver import ActionChains
import time
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 5)
action = ActionChains(driver)
driver.get("YourURL")
# you can also use time.sleep(5)
wait.until(expected_conditions.presence_of_element_located((By.ID, "audio-source")))
Src_URL = driver.find_element_by_id('audio-source').get_attribute('src')
print(Src_URL)

Other ways to fill text field, not send_keys

So I've gone to a few forums online but nothing seems to work. I am trying to fill a credit card field on a website, but when I use:
send_keys()
It scrambles the numbers. Is there any way to fill the text box similar to the way autocomplete does? Just send the entire string at once:
iframe = driver.find_element_by_xpath("//iframe[#name='__privateStripeFrame4']")
driver.switch_to.frame(iframe)
credit_card_text.click()
credit_card_text.send_keys(credit_card)
driver.switch_to.default_content()
You should use WebDriverWait
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Firefox()
driver.get("http://example.com")
iframe = driver.find_element_by_xpath("//iframe[#name='__privateStripeFrame4']")
driver.switch_to.frame(iframe)
credit_card = 12345678754325
credit_card_text = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.XPATH, '//*[#id="root"]/form/span[2]/label/input')))
credit_card_text.click()
credit_card_text.send_keys(credit_card)
If it doesn't work you can try using execute_script:
iframe = driver.find_element_by_xpath("//iframe[#name='__privateStripeFrame4']")
driver.switch_to.frame(iframe)
credit_card = 12345678754325
credit_card_text = driver.find_element_by_xpath(' //*[#id="root"]/form/span[2]/label/input')
driver.execute_script("arguments[0].setAttribute('value', '" + credit_card+"')", credit_card_text)
driver.switch_to.default_content()
Hope this helps!

Categories

Resources