How can I download a file using Selenium? - python

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)

Related

Send_keys to a textarea jsname in Python Selenium

I'm trying to 'send_keys' to a textarea in Google Reviews using Python Selenium :
This is the element:
<textarea jsname="B7I4Od" jsaction="focus:DTi7Pd; blur:PLbHqf; input:JD9Kbd; change:JD9Kbd; keyup:JD9Kbd; mouseup:nL5Qe" class="shklGc eFqywb T4CXLd" placeholder="Share your experience" aria-label="Enter review" id="Yc71gb" style="height: 90px;"></textarea>
I tried with:
driver.find_element((By.XPATH, '//*[#id="Yc71gb"]')).send_keys('text')
driver.find_element((By.XPATH, "//textarea[contains(#placeholder,'Share your experience')]")).send_keys('text')
driver.find_element((By.XPATH, "//textarea[contains(#aria-label,'Enter review')]")).send_keys('text')
driver.find_element((By.XPATH, "//textarea[contains(#jsname,'B7I4Od')]")).send_keys('text')
driver.find_element((By.CSS_SELECTOR, '#Yc71gb')).send_keys('text')
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "[aria-label='Enter review']"))).send_keys('text')
But none worked. Any idea?
Thank you.
The text area is in iframe
<iframe name="goog-reviews-write-widget" role="presentation" class="goog-reviews-write-widget" src="https://www.google.com/maps/api/js/ReviewsService.LoadWriteWidget2?key=AIzaSyAQiTKe3tivKXammrJ6ov6u8E7KwZPNFss&authuser=0&hl=en&pb=!2m1!1sChIJo2FtG0NpwokRn0ICTCCkHTw!3shttps%3A%2F%2Fwww.google.com!5sen!7b1&cb=18503887"></iframe>
so you first have to switch to iframe then you can interact with the text area :
WebDriverWait(driver, 20).until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[#name='goog-reviews-write-widget']")))
You'll need imports as well :
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
after that WebDriverWait line you can write the line to identify text area and send the keys.

How to click Elements on websites with Selenium Python

So, I'm not very familiar with Python nor HTML
But I made this code so I could vote in a poll on a website, as far as I'm concerned there is nothing morally wrong with this idea because it is encouraged to refresh your page so you can vote for the same person over and over again. I want to use the code to click a button.
Below is the code I've got so far
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
from selenium.webdriver.common.keys import Keys
import time
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://www.nfl.com/voting/rookies/")
So I've gotten as far as going onto the website but I'm not sure if the person I am going to vote for has an HTML ID/Class/Element, I'm not really sure how to find it with inspect element or if it even has an HTML ID/Class/Element. If I want to vote for someone like Justin Herbert of the LAC, how should my code look? How would I click the white button next to Justin with Python? Thank you!
From the driver.get we get a popup, an iframe to handle and we need to click on the div tag that responds to a player. You should be able to translate these steps to your player.
Popup:
<div class="slidedown-footer" id="slidedown-footer"><button class="align-right primary slidedown-button" id="onesignal-slidedown-allow-button">Allow</button><button class="align-right secondary slidedown-button" id="onesignal-slidedown-cancel-button">No Thanks</button><div class="clearfix"></div></div>
Iframe:
<iframe title="Content from Riddle" style="border: none; width: 100%; position: static; opacity: 1; height: 539px !important;" src="https://www.riddle.com/a/288390"></iframe>
Player:
<span class="list-title ng-binding" ng-bind-html="item.title">Salvon Ahmed, MIA</span>
For this we use the following:
driver.get("https://www.nfl.com/voting/rookies/")
wait=WebDriverWait(driver, 10)
wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, "#onesignal-slidedown-cancel-button"))).click()
wait.until(EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//iframe[#title='Content from Riddle']")))
wait.until(EC.element_to_be_clickable((By.XPATH, "//span[text()='Salvon Ahmed, MIA']/parent::div/parent::div/div[2]/div"))).click()
Import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

How to wait till page loads and then press the load more button in selenium?

Using selenium to load and page and need to click load more button, but after it clicks load more than 100 times
i m getting this error of element click intercepted. because after 100 times the page takes time to load. and code doesnt know where to click.
Tried increasing sleep time to 20 seconds also but at some points if page takes more than 20 seconds the code returns error
error :
ElementNotInteractableException: Message: element not interactable (Session info: chrome=75.0.3770.100)
code :
from selenium import webdriver
import time
import pandas as pd
driver = webdriver.Chrome('/Users/1/chromedriver.exe')
driver.get('https://simpletire.com/catalog?select=1&brand=61&query=catalog')
click_more=True
while click_more:
time.sleep(2)
driver.find_element_by_css_selector(".btn.btn-primary.btn-lg").click();
Consider introducing Explicit Wait to ensure that the button is there prior to attempting clicking it
Example 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
driver = webdriver.Chrome('/Users/1/chromedriver.exe')
driver.get('https://simpletire.com/catalog?select=1&brand=61&query=catalog')
click_more=True
while click_more:
WebDriverWait(driver, 30).until(EC.presence_of_element_located((By.CSS_SELECTOR, ".btn.btn-primary.btn-lg"))).click()
More information:
Python Selenium: Wait Support
Python Selenium: Waits
How to use Selenium to test web applications using AJAX technology
In these situations I typically stop the page load, perhaps scroll a couple of times and use screen coordinates with a macro tool like AppRobotic to click the button. Something like this should work for you:
import win32com.client
from win32com.client import Dispatch
x = win32com.client.Dispatch("AppRobotic.API")
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.Chrome('/Users/1/chromedriver.exe')
driver.get('https://simpletire.com/catalog?select=1&brand=61&query=catalog')
# wait 20 seconds per question
x.Wait(20000)
# scroll down a couple of times in case page javascript is waiting for user interaction
x.Type("{DOWN}")
x.Wait(2000)
x.Type("{DOWN}")
x.Wait(2000)
# forcefully stop pageload at this point
driver.execute_script("window.stop();")
# if clicking with Selenium still does not work here, use screen coordinates
x.MoveCursor(xCoord, yCoord)
x.MouseLeftClick
x.Wait(2000)
It would appear that you might be running into the google ad at the bottom of the page.
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
from selenium.common.exceptions import TimeoutException
driver = webdriver.Chrome()
driver.get('https://simpletire.com/catalog?select=1&brand=61&query=catalog')
click_more=True
wait = WebDriverWait(driver, 30)
while click_more:
try:
elem = wait.until(EC.visibility_of_element_located((By.XPATH, '//button[#class="btn btn-primary btn-lg"]')),
"Cannot find 'Load More' button")
elem.click()
except TimeoutException:
click_more = False
Using xpath and visibility_of_element_located I get the following exception:
selenium.common.exceptions.ElementClickInterceptedException: Message: element click intercepted: Element <button class="btn btn-primary btn-lg">...</button> is not clickable at point (591, 797). Other element would receive the click: <iframe id="google_ads_iframe_/21692090825/ST_FlexFooter_0" title="3rd party ad content" name="google_ads_iframe_/21692090825/ST_FlexFooter_0" width="970" height="90" scrolling="no" marginwidth="0" marginheight="0" frameborder="0" srcdoc="" style="border: 0px; vertical-align: bottom;" data-google-container-id="1" data-load-complete="true"></iframe>
You either need to close the google add or scroll the page down a little before attempting to click the button. Once that is done, the while loop should work.
Try the script below to keep clicking on that button until there is none left to click.
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support import expected_conditions as EC
with webdriver.Chrome() as driver:
wait = WebDriverWait(driver, 10)
driver.get('https://simpletire.com/catalog?select=1&brand=61&query=catalog')
while True:
try:
item = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "#load_button > button")))
except TimeoutException:
item = ""
if not item: break
driver.execute_script("arguments[0].scrollIntoView();", item)
item.click()

Unable to click on hidden AirPlay button element on Safari (mac) using the selenium webdriver

As part of testing using Python and Selenium, I intend to open a youtube link using selenium and want to click on the "AirPlay"button in order to send it across to the Apple TV.
Initially I had the problem with the element being hidden but that was taken care of using the ActionChains. The script executes but I do not see click being executed on the video played by which I could see the AppleTv name show up.
Below is the code:
from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver import ActionChains
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import os , sys
server_url = "http://10.0.10.4:4444/wd/hub"
capabilities = DesiredCapabilities.SAFARI
driver = webdriver.Remote(desired_capabilities=capabilities,
command_executor=server_url)
driver.get("https://www.youtube.com/watch?v=_YhrCp9m14k")
#air_play = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '//*[#id="move_player"]/div[28]/div[2]/div[2]/button[6]')))
air_play = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.CLASS_NAME, 'ytp-airplay-button')))
#air_play = WebDriverWait(driver, 20).until(EC.presence_of_element_located((By.XPATH, '//*[#id="text"]')))
#air_play = driver.find_element_by_css_selector('button.ytp-ariplay-button')
hover = ActionChains(driver).move_to_element(air_play)
hover.perform()
hover1 = ActionChains(driver).click_and_hold(air_play).perform()
The html element is as follows:
<button class="ytp-airplay-button ytp-button" title="AirPlay" style=""><svg
height="100%" version="1.1" viewBox="0 0 36 36" width="100%"><use
class="ytp-svg-shadow" NS1:href="#ytp-id-27"></use><path class="ytp-svg-
fill" d="M12,28 L24,28 L18,22 L12,28 Z M27,9 L9,9 C7.9,9 7,9.9 7,11 L7,23
C7,24.1 7.9,25 9,25 L13,25 L13,23 L9,23 L9,11 L27,11 L27,23 L23,23 L23,25
L27,25 C28.1,25 29,24.1 29,23 L29,11 C29,9.9 28.1,9 27,9 L27,9 Z" id="ytp-
id-27"></path></svg></ button>
The XPATH is as follows:
//*[#id="movie_player"]/div[28]/div[2]/div[2]/button[6]
The CSS Selector is as follows:
#movie_player > div.ytp-chrome-bottom > div.ytp-chrome-controls > div.ytp-
right- controls > button.ytp-airplay-button.ytp-button
Can someone help with as to why the button does not get clicked and show up the available Airplay options?
Before hovering over the video.
After hovering over the video and clicking on the AirPlay button.
I don't have Safari on a Mac so I can't repro this myself but I'm guessing the issue (from your screenshot) is that the icon isn't visible until the video area is hovered. By design, Selenium will not interact with elements that a user can't see. There are a couple ways to do this.
The user way... hover the video, hover the icon, and then click the icon. If you are trying to simulate a user, this is the method you want to use.
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions as EC
video = driver.find_element_by_css_selector("video")
ActionChains(driver).move_to_element(video).perform()
WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button[title='AirPlay']")).click()
The non-user way... click on it with JSE. With JSE we can click any element, visible or not. No user can click an invisible element so if you are trying to simulate a user, don't use this... use #1.
airplayButton = driver.find_element_by_css_selector("button[title='AirPlay']")
driver.execute_script("arguments[0].click();", airplayButton);

selenium not able to retrieve/read part of the website

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

Categories

Resources