I was trying to do a automated script to download some foreign exchange price historical data. These data are available at
https://www.dukascopy.com/swiss/english/marketwatch/historical/
However, if I just use Selenium to retrieve part of the website, I can't find this element in the website no matter how long I waited:
<iframe src="https://freeserv.dukascopy.com/2.0/?path=historical_data_feed/index&header=false&availableInstruments=l%3A&width=100%25&height=600&adv=popup" border="0" marginwidth="0" marginheight="0" frameborder="0" scrolling="no" width="100%" height="600"></iframe>
Apparently, the only thing selenium can read is the two elements ahead of the :
<script type="text/javascript">DukascopyApplet = {"type":"historical_data_feed","params":{"header":false,"availableInstruments":"l:","width":"100%","height":"600","adv":"popup"}};</script>
<script type="text/javascript" src="https://freeserv.dukascopy.com/2.0/core.js"></script>
Anyone know how to solve this problem? Many thanks.
Wait for the presence of the frame and then switch to it. Then, you can look for the elements inside:
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("https://www.dukascopy.com/swiss/english/marketwatch/historical/")
# wait for the frame to load and switch
wait = WebDriverWait(driver, 10)
iframe = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, ".mainContentBody iframe")))
driver.switch_to.frame(iframe)
# print out the bold radio button style texts
for item in driver.find_elements_by_css_selector("ul > li[data-group][data-instrument] strong"):
print(item.text)
driver.close()
Prints:
ADS.DE
ALV.DE
AUD/CAD
AUD/CHF
AUD/JPY
...
VOW3.DE
XAG/USD
XAU/USD
ZAR/JPY
Related
I am trying to automate the location selection process, however I am struggle with it.
So for, I can only open the menu and select the first item.
And my code is:
import bs4
from bs4 import BeautifulSoup
import selenium
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
driver = webdriver.Chrome(ChromeDriverManager().install())
url = 'https://www.ebay.com/b/Food-Beverages/14308/bn_1642947?listingOnly=1&rt=nc'
driver.get(url)
soup = BeautifulSoup(driver.page_source, 'html.parser')
button = driver.find_element_by_id('gh-shipto-click') //find the location button
button.click()
button2 = driver.find_element_by_id('gh-shipto-click-body-cnt') //open the menu
button2.click()
driver.find_element(By.XPATH,"//div[#role='menuitemradio']").click() //choose the first location
I believe the attribute "data-makeup-index" (show in the pic) would help, but I don't know how to use it.
Sine some of you may not able to find the "ship to" button. Here is the html code I copied from the web.
<li id="gh-shipto-click" class="gh-eb-li">
<div class="gh-menu">
<button _sp="m570.l46241" title="Ship to" class="gh-eb-li-a gh-icon" aria-expanded="false" aria-controls="gh-shipto-click-o" aria-label="Ship to Afghanistan"><i class="flgspr gh-flag-bg flaaf"></i><span>Ship to</span></button>
<i class="flgspr gh-flag-bg flaaf"></i>
I have found my answer as below:
driver.find_element(By.XPATH,"//div[#role='menuitemradio'][{an integer}]").click()
Although the Ship to was not visible to my location, I've inspected it from different Geo location and guess what I was able to find this elementstyle="display: none;
I've removed the none temporarily, and it got displayed.
<li id="gh-shipto-click" class="gh-eb-li gh-modal-active" style="display:none;" aria-hidden="false">
You could find the element by these XPath and handle the dropdown
#This XPath is taking you to the specific div where you need to provide the element index [1][2][3] the ID of this XPath is dynamic
driver.find_element_by_xpath("((((//*[contains(#id,'nid-')])[2])//child::div/div")
driver.find_element_by_xpath("//*[#class='cn']")
I know you got your solution, but this what I've tried It might help
I want to download a xlsx file from a website. And to do that I have to click on a button and I can't find it with my Python code. With my current Python code I can open the website using Selenium and open the download page and what I want is to click on "Excel: extension XLSx" button.
options=webdriver.ChromeOptions()
options.add_argument("--start-maximized")
driver=webdriver.Chrome(executable_path=path_web_crawler+"chromedriver.exe",chrome_options=options)
driver.get("https://www.ine.es/jaxiT3/Datos.htm?t=25171")
time.sleep(3)
driver.find_element_by_xpath("//input[#name='btnDescargaForm']").click()
What I tried to detect the button
elem=driver.find_element_by_xpath("//input[#value='xlsx']")
driver.execute_script("arguments[0].click();",elem)
<iframe title="Popup content - Rising content" id="thickBoxINEfrm" name="thickBoxINEfrm" frameborder="0" width="100%" height="100%" marginheight="0" marginwidth="0" tabindex="0" onload=";autoResizeThickBox(this)"></iframe>
Your element is in an iframe.
Import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Full Code:
driver.get("https://www.ine.es/jaxiT3/Datos.htm?t=25171")
wait = WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.XPATH,"//input[#name='btnDescargaForm']"))).click()
wait.until(EC.frame_to_be_available_and_switch_to_it((By.ID,"thickBoxINEfrm")))
elem=wait.until(EC.presence_of_element_located((By.XPATH,"//input[#value='xlsx']")))
driver.execute_script("arguments[0].click();",elem)
I am trying this code to click on the javascript button. In the first frame you find the content, but when I place myself in the second html there is no menu.
How do I click on the button?
Code trials:
driver.switch_to.default_content()
driver.find_element_by_tag_name('frameset')
driver.switch_to_frame(1)
driver.find_element_by_tag_name('html')
print(driver.page_source)
driver.find_element_by_tag_name('frameset')
driver.switch_to_frame(1)
driver.find_element_by_tag_name('html')
print(driver.page_source)
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
</head><frameset cols="170px,100%" framespacing="0" border="0" frameborder="0">
<frame scrolling="no" name="menu" id="menu" src="menu.jsp" />
<frame scrolling="yes" name="main" id="main" src="main.jsp" />
</frameset>
As the the desired element is within an multiple <iframe>s so you have to:
Induce WebDriverWait for the parent frame to be available and switch to it.
Induce WebDriverWait for the child frame to be available and switch to it.
Induce WebDriverWait for the desired element to be clickable.
You can use the following solution:
Code Block:
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//frame[contains(#src, 'login')]")))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH,"//frame[#id='menu' and #name='menu'][contains(#src, 'menu')]")))
WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.PARTIAL_LINK_TEXT, "squeda Avanzada"))).click()
Here you can find a relevant discussion on Ways to deal with #document under iframe
My website form have updated and my script is no more working. I cannot fix it because I'm not able to find how to select in a dropdown content using selenium chrome web driver and python.
formattedstate is the value of a formatted data (read from a file)
driver.find_element_by_css_selector(f"option[title='{formattedState}']").click()
driver.find_element_by_xpath("//*[text()='{formattedState}']").click()
driver.find_element_by_css_selector(f"option[value='{formattedState}']").click()
This is the data of the dropdown content from the webform. I selected the first state in the dropdown = Alabama
<input aria-valuetext="" role="combobox" tabindex="0"
placeholder="State/Province/Region" readonly="" height="100%" size="1" autocomplete="off" value="" data-spm-anchor-id="a2g0o.placeorder.0.i14.5f0b321eC7zfLx">
<li class="next-menu-item" title="Alabama" data-spm-anchor-id="a2g0o.placeorder.0.i17.5f0b321eC7zfLx">Alabama</li>
It should select the correct state in the dropdown content
First try to click to the combobox, then wait until state option(li) element is visible and click.
In code below, I used css selector to get li by title. If you want to find element by text, use:
wait.until(ec.visibility_of_element_located((By.XPATH, f"//li[.='{state}' and #class = 'next-menu-item']"))).click()
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.ui import WebDriverWait
driver = webdriver.Chrome()
wait = WebDriverWait(driver, 10)
state = "Alabama"
driver.find_element_by_css_selector('input[placeholder="State/Province/Region"]').click()
wait.until(ec.visibility_of_element_located((
By.CSS_SELECTOR, f"li.next-menu-item[title='{state}']"))).click()
JS SetAttribute works surprisingly well for Combobox. Try
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("document.getElementById('//id of element').setAttribute('value', '//value to set')");
// to click
js.executeScript("arguments[0].click();", element);
This question already has answers here:
Unable to locate the child iframe element which is within the parent iframe through Selenium in Java
(2 answers)
Multiple iframe tags Selenium webdriver
(2 answers)
Closed 3 years ago.
I am trying to switch into second iframe of the website for personal auto-filler for my business.
Just in case I might get marked as dup, I tried Python Selenium switch into an iframe within an iframe already and sadly got not much out of it.
Here are html codes for two iframes. Second iframe is within the first one:
<div id="tab2_1" class="cms_tab_content1" style="display: block;">
<iframe id="the_iframe"src=
"http://www.scourt.go.kr/portal/information/events/search/search.jsp">
</iframe> <!-- allowfullscreen --></div>
<div id="contants">
<iframe frameborder="0" width="100%" height="1100" marginheight="0"
marginwidth="0" scrolling="auto" title="나의 사건검색"
src="http://safind.scourt.go.kr/sf/mysafind.jsp
sch_sa_gbn=&sch_bub_nm=&sa_year=&sa_gubun=&sa_serial=&x=&
y=&saveCookie="></iframe>
<noframes title="나의사건검색(새창)">
<a href="http://safind.scourt.go.kr/sf/mysafind.jspsch_sa_gbn
=&sch_bub_nm=&sa_year=&sa_gubun=&sa_serial=&x=&y=&
saveCookie=" target="_blank"
title="나의사건검색(새창)">프레임이 보이지 않을경우 이곳을 클릭해주세요</a></noframes></div>
Just for a reference- so far, I tried these:
#METHOD-1
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.ID,"the_iframe"))
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"#contants > iframe"))
#METHOD-2
driver.switch_to.frame(driver.find_element_by_xpath('//*[#id="the_iframe"]'))
driver.WAIT
driver.switch_to.frame(driver.find_element_by_css_selector('//*[#id="contants"]/iframe'))
driver.WAIT
#METHOD-3
iframe = driver.find_elements_by_tag_name('iframe')[0]
driver.switch_to.default_content()
driver.switch_to.frame(iframe)
driver.find_elements_by_tag_name('iframe')[0]
Here is the entire code I have right now:
import time
import requests
from bs4 import BeautifulSoup as SOUP
import lxml
import re
import pandas as pd
import numpy as np
from selenium import webdriver
from selenium.webdriver.support import ui
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support.ui import Select
import psycopg2
#ID and Password for autologin
usernameStr= 'personalinfo'
passwordStr= 'personalinfo'
driver = webdriver.Chrome('./chromedriver')
ultrawait = WebDriverWait(driver, 9999)
ConsumerName=""
COURTNO=""
CASENO=""
CaseYear=""
CaseBun=""
CaseSerial=""
#AutoLogin
driver.get("http://PERSONALINFO")
username = driver.find_element_by_name('userID')
username.send_keys(usernameStr)
userpassword = driver.find_element_by_name('userPassword')
userpassword.send_keys(passwordStr)
login_button=driver.find_elements_by_xpath("/html/body/div/div[2]/div/form/input")[0]
login_button.click()
#Triggered when str of URL includes words in look_for
def condition(driver):
look_for = ("SangDamPom", "jinHaengNo")
url = driver.current_url
WAIT = WebDriverWait(driver, 2)
for s in look_for:
if url.find(s) != -1:
url = driver.current_url
html = requests.get(url)
soup = SOUP(html.text, 'html.parser')
soup = str(soup)
#Some info crawled
CN_first_index = soup.find('type="text" value="')
CN_last_index = soup.find('"/></td>\n<t')
ConsumerName=soup[CN_first_index+19:CN_last_index]
ConsumerName.replace(" ","")
#Some info crawled
CTN_first_index = soup.find('background-color:#f8f8f8;')
CTN_last_index = soup.find('</td>\n<td height="24"')
COURTNO = soup[CTN_first_index+30:CTN_last_index]
COURTNO = COURTNO.replace('\t', '')
#Some info crawled
CAN_first_index = soup.find('가능하게 할것(현제는 적용않됨)">')
CAN_last_index = soup.find('</a></td>\n<td height="24"')
CASENO=soup[CAN_first_index+19:CAN_last_index]
CaseYear=CASENO[:4]
CaseBun=CASENO[4:-5]
CaseSerial=CASENO[-5:]
print(ConsumerName, COURTNO, CaseYear, CaseBun, CaseSerial)
#I need to press this button for iframe I need to appear.
frame_button=driver.find_elements_by_xpath("//*[#id='aside']/fieldset/ul/li[2]")[0]
frame_button.click()
time.sleep(1)
#Switch iframe
driver.switch_to.frame(driver.find_element_by_xpath('//*[#id="the_iframe"]'))
driver.wait
driver.switch_to.frame(driver.find_element_by_xpath("//iframe[contains(#src,'mysafind')]"))
time.sleep(1)
#Insert instit.Name
CTNselect = Select(driver.find_element_by_css_selector('#sch_bub_nm'))
CTNselect.select_by_value(COURTNO)
#Insert Year
CYselect = Select(driver.find_element_by_css_selector('#sel_sa_year'))
CYselect.select_by_value(CaseYear)
#Insert Number
CBselect = Select(driver.find_element_by_css_selector('#sa_gubun'))
CBselect.select_by_visible_text(CaseBun)
#사건번호 입력 (숫자부분)
CS_Insert = WAIT.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#sa_serial")))
CS_Insert.click()
CS_Insert.clear()
CS_Insert.send_keys(CaseSerial)
#Insert Name
CN_Insert = WAIT.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#ds_nm")))
CN_Insert.click()
CN_Insert.clear()
CN_Insert.send_keys(ConsumerName)
break
ultrawait.until(condition)
Don't mind indention errors, problem of copy-paste.
I think its from #Switch iframe I have issue with.
Those inputs that come after #Switch iframe are all functional. I've tested them by opening iframe at another tab.
You need to deal with your frames separately:
When you finished working with one of them and want to switch to another -- you need to do:
driver.switch_to.default_content()
then switch to another one.
Better to use explicit wait for switching to the frame:
from selenium.webdriver.support import ui
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
ui.WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it((By.CSS_SELECTOR, "#contants>iframe")))
wherein By you can use any locator.
As per your html structure, both the iframes are different and the second one is not in between the first one. It would have been inside the first one if the html structure was like:
<div>
<iframe1>
<iframe2>
</iframe2>
</iframe1>
</div>
But as your first <div> and first <iframe> are ending before starting the second div and iframe, it means both the iframes are seperate.
So, according to your requirements, you just need to switch to the second iframe which can be done using:
WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it(By.CSS_SELECTOR,"second iframe css"))
Updated Answer:
Try the code:
driver.switch_to.frame(driver.find_element_by_xpath('//*[#id="the_iframe"]'))
driver.WAIT
driver.switch_to.frame(driver.find_element_by_xpath('//iframe[contains(#src,'mysafind')]'))
driver.WAIT