User8392 User8392 - 2 months ago 7
HTML Question

How to switch to frame source in selenium

I want to click an frame source's radio button, but it doesn't work. I think, frame source doesn't have iframe id or name.
my code is this.

import time
from selenium import webdriver
Url='https://www.youtube.com/watch?v=eIStvhR347g'
driver = webdriver.Firefox()
driver.get('https://video-download.online')
driver.find_element_by_id("link").send_keys(Url)
driver.find_element_by_id("submit").click()
time.sleep(5)

#this part is problems... don't working
driver.switch_to_frame(driver.find_element_by_xpath('//iframe'))
driver.find_elements_by_xpath("//*[@type='radio']")[0].click()
driver.find_element_by_xpath(".//button[contains(text(),'Proceed')]").click()


html source is this.

<html>
<head>
<meta charset="utf-8"/>

...

<script>
if (top.location !== location) {
top.location = self.location;
}
if (location.host !== 'video-download.online' && location.host !== 'beta.video-download.online') {
eval("location.href=''+'//'+'video-download.online';");
}
</script>
<meta name="msapplication-tap-highlight" content="no"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"/>
<meta name="author" content="Luca Steeb"/>
<meta name="theme-color" content="#008679"/>
<meta name="description" content="Download from this uploaded.net premium link generator with highspeed. For free."/>
<meta property="og:title" content="Video-Download.online"/>
<meta property="og:description" content="Download videos, mp3s and playlists from 1979 sites - for free."/>
<meta property="og:type" content="website"/>
<meta property="og:url" content="video-download.online"/>
<meta property="fb:page_id" content="1143492155680932"/>
<meta property="og:image" content="//video-download.online/img/logo.jpg"/>
<link rel="shortcut icon" href="/favicon.ico?1"/>
<link rel="icon" sizes="192x192" href="/img/logo_small.jpg"/>
<link rel="apple-touch-icon" href="/img/apple-touch-icon.png"/>
<link rel="search" type="application/opensearchdescription+xml" title="Video-Download.online" href="/opensearch.xml"/>
<title>
Online Video Download
</title>
<meta name="robots" content="noindex, nofollow"/>
<link rel="stylesheet" href="/css/bt.css"/>
<link rel="stylesheet" href="/css/style.css"/>
<noscript><iframe height=0 src="//www.googletagmanager.com/ns.html?id=GTM-TWMNRP"style=display:none;visibility:hidden width=0></iframe></noscript><script>!function(e,t,a,n,r){e[n]=e[n]||[],e[n].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var g=t.getElementsByTagName(a)[0],m=t.createElement(a),s="dataLayer"!=n?"&l="+n:"";m.async=!0,m.src="//www.googletagmanager.com/gtm.js?id="+r+s,g.parentNode.insertBefore(m,g)}(window,document,"script","dataLayer","GTM-TWMNRP")</script>

<script>(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');ga('create','UA-54289597-5','auto');ga('send','pageview');</script>




<script>function send(action) { ga('send', 'event', 'button', 'click', 'download-' + action) }</script>
<script async src="/js/jquery.js"></script>
<script>function _(n,i){i?window[n]?i():setTimeout(function(){_(n,i)},100):window.jQuery?window.jQuery(document).ready(function(){n(window.jQuery)}):setTimeout(function(){_(n)},100)}</script>
</head>

<body>

<header class="navbar navbar-info navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle no-waves" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>

<div class="nav-brand">
<a class="navbar-brand" href="/">
<img class="logo" src="/img/logo.svg" alt=""/>

<div class="parent">

Video-Download<small>.online</small>
<br/>
<span class="small-text">1979 sites officially supported</span>

<span id="changelog"></span>
</div>

<span class="clear"></span>
</a>
</div>
</div>

<div class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<div class="social">
<div class="fb-like fb-nav" data-href="https://www.facebook.com/VideoDownload.online"
data-layout="button_count" data-action="like" data-show-faces="false" data-share="true">
</div>
</div>
<div class="social-close" title="Hide all social buttons">&times;</div>



<li class=" ">
<a href="/">
Home
</a>
</li>
<li class=" ">
<a href="/sites">
Sites
</a>
</li>
<li class=" ">
<a href="/contact">
Contact
</a>
</li>
<!--html.navItem('/app', 'Mobile App')-->
</ul>
</div>
</div>
</header>

<noscript class="fixed">
<div class="container">Please enable javascript. Video Download and almost all other sites don't work properly
without it.
</div>
</noscript>

<div id="alert" class="alert alert-fixed alert-dismissible m-t-15 hidden">
<div class="container relative">
<span id="alertText"></span>
<span class="close-alert" onclick="_(function() { $('#alert').remove();$('body').removeClass('alert-showing') })" title="close">×</span>
</div>
</div>

<main class="container">
<div>
<h1>Legal</h1>

<div style="width: 50%;" class="center">

</div>
</main>

<script src="/sweetalert/sweetalert.js"></script>
<link rel="stylesheet" href="/sweetalert/sweetalert.css">



<script src="/waves/waves.min.js"></script>
<script src="/js/dropdown.js"></script>
<script src="/js/main.js"></script>
<script src="/js/bootstrap.js"></script>



<script type="text/javascript">/* <![CDATA[ */(function(d,s,a,i,j,r,l,m,t){try{l=d.getElementsByTagName('a');t=d.createElement('textarea');for(i=0;l.length-i;i++){try{a=l[i].href;s=a.indexOf('/cdn-cgi/l/email-protection');m=a.length;if(a&&s>-1&&m>28){j=28+s;s='';if(j<m){r='0x'+a.substr(j,2)|0;for(j+=2;j<m&&a.charAt(j)!='X';j+=2)s+='%'+('0'+('0x'+a.substr(j,2)^r).toString(16)).slice(-2);j++;s=decodeURIComponent(s)+a.substr(j,m-j)}t.innerHTML=s.replace(/</g,'&lt;').replace(/>/g,'&gt;');l[i].href='mailto:'+t.value}}catch(e){}}}catch(e){}})(document);/* ]]> */</script></body>
</html>


frame source is this.

<html>
<head>
<meta charset="utf-8"/>
<meta name="robots" content="noindex, nofollow"/>

...

<link rel="stylesheet" href="/css/bt.css"/>
<link rel="stylesheet" href="/css/style.css"/>
<script src="/js/jquery.js"></script>
<style>body{margin:0!important;}tr{clear:both;cursor:pointer;}td{padding:0 20px 0 0;white-space:nowrap;}.radio{margin-top:5px;margin-bottom:5px;}.small{padding:0;font-size:85%;}@media (max-width: 319px) {table{font-size:12px;}}@media (max-width: 480px) {td{padding:0 5px 0 0;}.small{font-size:50%;}}</style>
</head>
<body>
<form id="format" method="post">
<input name="id" type="hidden" value="isxklqy5blw9of7"/>
<table>
<tr>
<td class="small">
<div class="">
<div class="radio " id="undefined-wrapper">
<label class="text-capitalize" for="undefined">
<input id="undefined" name="format" type="radio" value="undefined" onchange="" undefined required />
<span class=circle></span><span class=check></span>
<span class="grey-text"></span>
</label>
</div>
</div>
</td>
<td>I don't care</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td class="small">
<div class="">
<div class="radio " id="160-wrapper">
<label class="text-capitalize" for="160">
<input id="160" name="format" type="radio" value="160" onchange="" undefined required />
<span class=circle></span><span class=check></span>
<span class="grey-text"></span>
</label>
</div>
</div>
</td>
<td>256x144</td>
<td></td>
<td>
30 FPS
</td>
<td>23.2 MB</td>
</tr><tr>
<td class="small">
<div class="">
<div class="radio " id="133-wrapper">
<label class="text-capitalize" for="133">
<input id="133" name="format" type="radio" value="133" onchange="" undefined required />
<span class=circle></span><span class=check></span>
<span class="grey-text"></span>
</label>
</div>
</div>
</td>
<td>426x240</td>
<td></td>
<td>
30 FPS
</td>
<td>51.2 MB</td>
</tr><tr>
<td class="small">
<div class="">
<div class="radio " id="134-wrapper">
<label class="text-capitalize" for="134">
<input id="134" name="format" type="radio" value="134" onchange="" undefined required />
<span class=circle></span><span class=check></span>
<span class="grey-text"></span>
</label>
</div>
</div>
</td>
<td>640x360</td>
<td></td>
<td>
30 FPS
</td>
<td>65.4 MB</td>
</tr><tr>
<td class="small">
<div class="">
<div class="radio " id="135-wrapper">
<label class="text-capitalize" for="135">
<input id="135" name="format" type="radio" value="135" onchange="" undefined required />
<span class=circle></span><span class=check></span>
<span class="grey-text"></span>
</label>
</div>
</div>
</td>
<td>854x480</td>
<td></td>
<td>
30 FPS
</td>
<td>138.0 MB</td>
</tr><tr>
<td class="small">
<div class="">
<div class="radio " id="136-wrapper">
<label class="text-capitalize" for="136">
<input id="136" name="format" type="radio" value="136" onchange="" undefined required />
<span class=circle></span><span class=check></span>
<span class="grey-text"></span>
</label>
</div>
</div>
</td>
<td>1280x720</td>
<td>HD</td>
<td>
30 FPS
</td>
<td>272.2 MB</td>
</tr><tr>
<td class="small">
<div class="">
<div class="radio " id="298-wrapper">
<label class="text-capitalize" for="298">
<input id="298" name="format" type="radio" value="298" onchange="" undefined required />
<span class=circle></span><span class=check></span>
<span class="grey-text"></span>
</label>
</div>
</div>
</td>
<td>1280x720</td>
<td>HD</td>
<td>
60 FPS
</td>
<td>385.0 MB</td>
</tr><tr>
<td class="small">
<div class="">
<div class="radio " id="137-wrapper">
<label class="text-capitalize" for="137">
<input id="137" name="format" type="radio" value="137" onchange="" undefined required />
<span class=circle></span><span class=check></span>
<span class="grey-text"></span>
</label>
</div>
</div>
</td>
<td>1920x1080</td>
<td>Full HD</td>
<td>
30 FPS
</td>
<td>535.0 MB</td>
</tr><tr>
<td class="small">
<div class="">
<div class="radio " id="299-wrapper">
<label class="text-capitalize" for="299">
<input id="299" name="format" type="radio" value="299" onchange="" undefined required />
<span class=circle></span><span class=check></span>
<span class="grey-text"></span>
</label>
</div>
</div>
</td>
<td>1920x1080</td>
<td>Full HD</td>
<td>
60 FPS
</td>
<td>707.0 MB</td>
</tr>
</table>
<button class="btn center" type="submit">Proceed &raquo;</button>
</form>
</body>
<script>
$('tr').click(function() {
$(this).find('input').prop('checked', true);
});
</script>
<script src="/waves/waves.min.js"></script>
<script>
Waves.attach('.btn', ['waves-light']);
Waves.init();
</script>


html and frame sources are very long code, you can be check this full code.

html link

frame link

and I tried these codes, but don't work.

driver.switch_to_frame(driver.find_element_by_xpath('//iframe[contains(@name, "frame")]'))
driver.switch_to_frame(driver.find_element_by_tag_name("iframe"))
driver.switch_to_frame(driver.find_element_by_xpath('//iframe'))
driver.switch_to_frame(0)


these iframe switching codes are any exception is nothing, but result is '[]'.

>>> driver.switch_to_frame(driver.find_element_by_xpath('//iframe'))
>>> driver.find_elements_by_xpath("//*[@type='radio']")
[]
>>> driver.find_elements_by_xpath("//*[@type='radio']")[0].click()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range


I needs your help. thanks you.

Answer

As I'm seeing on this url, there are multiple iframe present while, you are trying to switch to iframe with it's tagName only which will switch to first find iframe in order while your desired iframe is at 4th index which has no id and name attribute present, so you should try using CSS_SELECTOR with WebDriverWait using EC.frame_to_be_available_and_switch_to_it which will try to wait until desired iframe to be available and then switch to it as below working code :-

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

wait = WebDriverWait(driver, 10)

wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe:not([id]):not([name])")))

#now do your stuff to find element inside this iframe

#after doing all stuff inside this iframe switch back to default content for further steps
driver.switch_to_default_content()

Note:- You can also consider below one of these options to switch your desired iframe :-

wait.until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, ".//iframe[not(@name) and not(@id)]")))

or

 wait.until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "iframe[src*='selectFormat']"))) 

or using index :-

wait.until(EC.frame_to_be_available_and_switch_to_it(3))