Not able to click on the button using Selenium - html

<button class="css-obkt16-button" type="button"><span class="css-1mhnkuh">Download CSV</span></button>
I am trying to click on the highlighted button 'Download CSV' having the above HTML code and save the csv file at some particular location, but I am not able to do so. The file is getting downloaded in Downloads folder.
My python code:
def scrape_data():
DRIVER_PATH = r"C:\chrome\chromedriver.exe"
driver = webdriver.Chrome(DRIVER_PATH)
driver.get('Link to the dashboard')
time.sleep(20)
buttons = driver.find_element(By.XPATH,"//button/span[text()='Download CSV']")
time.sleep(5)
driver.execute_script("arguments[0].click();", buttons)
driver.quit()
So please suggest a way to search via the button text) and save the file to a particular location??

To download the file on specific location you can try like blow.
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_experimental_option("prefs", {
"download.default_directory": r"C:\Data_Files\output_files"
})
s = Service('C:\\BrowserDrivers\\chromedriver.exe')
driver = webdriver.Chrome(service=s, options=options)

You should not use hardcoded sleeps like time.sleep(20). WebDriverWait expected_conditions should be used instead.
Adding a sleep between getting element and clicking it doesn't help in most cases.
Clicking element with JavaScript should be never used until you really have no alternative.
This should work in case the button you trying to click is inside the visible screen area and the locator is unique.
def scrape_data():
DRIVER_PATH = r"C:\chrome\chromedriver.exe"
driver = webdriver.Chrome(DRIVER_PATH)
wait = WebDriverWait(driver, 30)
driver.get('Link to the dashboard')
wait.until(EC.element_to_be_clickable((By.XPATH, "//button[contains(.,'Download CSV')]"))).click()

Related

Selenium - How to automatically Download PDF Files of Web Page if there is no Download Button?

1.) I'am trying to Download the Article PDF Files from multiple web pages to a local folder on the computer. But there is now "Download PDF" button on the web pages. What would be the Quickest and Best way to do this with Selenium ?
2.) One way I have thought of is to use the Keyboard Keys for Print, "Control"- "P", but inside Selenium, none of the Keyboard Keys are working when i run the program. The Code is below,
from selenium import webdriver
import chromedriver_binary # Adds chromedriver binary to path
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import time
driver = webdriver.Chrome()
driver.maximize_window() # Makes Full Screen of the Window Browser
time.sleep(4)
url = 'https://finance.yahoo.com/news/why-warren-buffett-doesnt-buy 152303112.html'
driver.get(url)
time.sleep(10)
a = ActionChains(driver)
a.key_down(Keys.CONTROL).send_keys('P').key_up(Keys.CONTROL).perform()
You can do that by using ChromeOptions() and have a setting id, origin etc.
Also you can give savefile.default_directory to save the PDF file.
Code:
import time
from selenium import webdriver
import json
Options = webdriver.ChromeOptions()
settings = {
"recentDestinations": [{
"id": "Save as PDF",
"origin": "local",
"account": "",
}],
"selectedDestinationId": "Save as PDF",
"version": 2
}
prefs = {'printing.print_preview_sticky_settings.appState': json.dumps(settings), 'savefile.default_directory': 'C:\\Users\\****\\path\\'}
Options.add_experimental_option('prefs', prefs)
Options.add_argument('--kiosk-printing')
driver_path = r'C:\\Users\\***\\***\\chromedriver.exe'
driver = webdriver.Chrome(options=Options, executable_path=driver_path)
driver.maximize_window() # Makes Full Screen of the Window Browser
time.sleep(4)
url = 'https://finance.yahoo.com/'
driver.get(url)
time.sleep(2)
driver.execute_script('window.print();')
Output:
You should see a PDF file in the directory like this:
Update:
driver_path = r'C:\\Users\\***\***\\chromedriver.exe'
driver = webdriver.Chrome(options=Options, executable_path=driver_path)

Python Selenium Popup

# Setup
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchAttributeException, NoAlertPresentException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
PATH = "C:\Program Files (x86)\chromedriver.exe"
driver = webdriver.Chrome(PATH)
driver.get("https://am1.badoo.com/sv/mobile/")
driver.maximize_window()
username = "*************"
password = "*************"
print(driver.title)
time.sleep(5)
search = driver.find_element_by_xpath('//*[#id="header"]/div/div[2]/div/div[2]/a')
search = driver.find_element_by_partial_link_text('Logga in')
search.send_keys(Keys.RETURN)
time.sleep(5)
print("Login in")
search = driver.find_element_by_name('email')
search.send_keys(username)
search = driver.find_element_by_name('password')
search.send_keys(password)
time.sleep(2)
search = driver.find_element_by_xpath('//*[#id="page"]/div[1]/div[3]/section/div/div/div[1]/form/div[5]/div/div[1]/button').click()
time.sleep(5)
# klickar på like knappen
search = driver.find_element_by_xpath('//*[#id="mm_cc"]/div[1]/section/div/div[2]/div/div[2]/div[1]/div[1]').click()
time.sleep(1)
#popup
#Switch the control to the Alert window
search = driver.switch_to.alert
#Retrieve the message on the Alert window
message=search.text
print ("Alert shows following message: "+ message )
time.sleep(2)
# Or Dismiss the Alert using
search.dismiss()
Hey my question is that I cant understand how to handle a popup. Trying to make a automation for badoo the dating application. And when you like the first person a popup appers. But I cant find or firgure out how to connect that popup so I can click decline/ accept.
Can any one help me out?
Thanks in advance :)
Screen of popup:
Can't figure out how to copy html code, but this is screens of it:
If the popup has the same text and format every single time, you can use pyautogui(python library) to detect the popup and move the mouse to the position of "Nej" and click it.

Using Python 3.7 and Selenium, I can't figure out how to troubleshoot my code for out of Viewport elements

I am trying to use various methods to troubleshoot my code to figure out why I can't use the "actions.move_to_element" method to move to an offscreen element, and click on it.
I am trying to get this line of code:
Off_Screen_Element = driver.find_element_by_class_name("c-btn-cta")
to act on this HTML element, which I must scroll to see. It is a button to accept the conditions of me booking a class time:
<button class="c-btn-cta c-btn-cta--chevron modal-class-action js-terms-agreement-cta" data-class-action="book-class" data-class-action-step="class-action-confirmation" data-workout-id="205911" data-club-id="229" aria-disabled="false" data-waitlistable="true">Confirm</button>
I get no syntax error, but when I use this line of code:
print(Off_Screen_Element.text)
it returns nothing. No exception or error. Just nothing. What am I doing wrong?
The key chunk of code I am using is this. Note, some is commented out for trouble-shooting I am trying to do. There is a large chunk of code of this script I am not posting, as it is working fine.
import datetime
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
#Using Firefox to access the Web
profile = webdriver.FirefoxProfile()
#options = webdriver.FirefoxOptions()
#profile.set_preference("dom.disable_beforeunload", True)
profile.set_preference("dom.webnotifications.enabled", False)
profile.update_preferences()
#profile.set_preference("dom.push.enabled", False)
driver = webdriver.Firefox(firefox_profile=profile)
driver.maximize_window()
driver.find_element_by_id("js-workout-booking-agreement-input").click()
Off_Screen_Element = driver.find_element_by_class_name("c-btn-cta")
#actions = ActionChains(driver)
#actions.move_to_element(Off_Screen_Element).click()
print(Off_Screen_Element.text)
Edit: This is the entire script:
import datetime
import time
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
#Using Firefox to access the Web
profile = webdriver.FirefoxProfile()
#options = webdriver.FirefoxOptions()
#profile.set_preference("dom.disable_beforeunload", True)
profile.set_preference("dom.webnotifications.enabled", False)
profile.update_preferences()
#profile.set_preference("dom.push.enabled", False)
driver = webdriver.Firefox(firefox_profile=profile)
driver.maximize_window()
# Open the website
driver.get('https://www.goodlifefitness.com/book-workout.html#no-redirect')
time.sleep(8)
# click on the sign in tab to get Login Window
driver.find_element_by_class_name('c-header__login-text').click()
# finding the Login Window User ID Box and sending the Login ID
User_ID = driver.find_element_by_class_name('js-login-email')
User_ID.send_keys('yyyyyyy')
#Finding the Login Window Password Box and sending the Password
Password = driver.find_element_by_class_name('js-login-password')
Password.send_keys('xxxxxxx')
#Finding the Login Window Log-In Button and Clicking on it
driver.find_element_by_class_name('js-login-submit').click()
#Pause a few seconds until the My Account Button appears
time.sleep(5)
#Find the unordered list that contains the 4th day (data-index 3) and then click on the element that is the 4th day
driver.find_element_by_xpath("//ul/li[#data-index='3']").click()
time.sleep(5)
Day_of_Timeslot = driver.find_element_by_xpath('//div[#id="day-number-4"]')
Precise_Timeslot = Day_of_Timeslot.find_element_by_xpath(".//li[#data-index='2']")
Actual_Button = Precise_Timeslot.find_element_by_xpath(".//button[#data-class-action='book-class']").click()
driver.find_element_by_id("js-workout-booking-agreement-input").click()
WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button[data-class-action='book-class']"))).click()
#Off_Screen_Element = driver.find_element_by_class_name("c-btn-cta")
#actions = ActionChains(driver)
#actions.move_to_element(Off_Screen_Element).click()```
It seems element is not visible on the page. Use WebDriverWait() and wait for element_to_be_clickable() and following css selector for the button
print(WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button[data-class-action='book-class']"))).text)
WebDriverWait(driver,20).until(EC.element_to_be_clickable((By.CSS_SELECTOR,"button[data-class-action='book-class']"))).click()
You need to import below libraries
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By

Dash open tkinter file select dialog on click button

I am trying to open a file dialog to select some local files. Apparently, Dash does not have this option build in, so I try to do it with tkinter. I find the Dash syntax very confusing with all these strange dependencies. When I run the example below, the file dialog opens as soon as I start the script, but not when I click the button. I desire the opposite behavior. The file selector dialog should open when I click the button and not when after starting the script.
from tkinter import Tk, filedialog
...
### Load files
#app.callback(
Output('B_add-files', 'value'),
[Input('B_add-files', 'n_clicks')],
[State('files-check', 'value')] )
def select_files(n_clicks, options):
if n_clicks is not None:
root = Tk()
root.withdraw()
root.call('wm', 'attributes', '.', '-topmost', True)
if 'by-dir' not in options:
files = filedialog.askopenfilename(multiple=True)
files = [abspath(i) for i in files]
for i in files:
assert isfile(i)
else:
dir_ = filedialog.askdirectory()
if isinstance(dir_ , tuple):
dir_ = []
if len(dir_) != 0:
files = glob(join(dir_, join('**', '*.mzXML')), recursive=True)
else:
files = []
if len(files) != 0:
mint.files += files
root.destroy()
return str(n_clicks)
This code now works most of the time. Only, if I click on the button multiple times, sometime the server stops and I get the error:
Tcl_AsyncDelete: async handler deleted by the wrong thread
Perhaps you’re looking for the Upload component... https://dash.plot.ly/dash-core-components/upload
If not, then your Input dependency should be on the “n_clicks” attribute of your button, rather than on “children”: https://dash.plot.ly/dash-core-components/button

Get specific informaion from html code

The idea is to collect all soundcloud users' id's (not names) who posted tracks that first letter is e.g. "f" in the period in our case of "past year".
I used filters on soundcloud and got results in the next URL: https://soundcloud.com/search/sounds?q=f&filter.created_at=last_year&filter.genre_or_tag=hip-hop%20%26%20rap
I found the first user's id ("wavey-hefner") in the follow line of html code:
<a class="sound__coverArt" href="/wavey-hefner/foreign" draggable="true">
I want to get every user's id from the whole html.
My code is:
import requests
import re
from bs4 import BeautifulSoup
html = requests.get("https://soundcloud.com/search/sounds?q=f& filter.created_at=last_year&filter.genre_or_tag=hip-hop%20%26%20rap")
soup = BeautifulSoup(html.text, 'html.parser')
for id in soup.findAll("a", {"class" : "sound_coverArt"}):
print (id.get('href'))
It returns nothing :(
The page is rendered in JavaScript. You can use Selenium to render it, first install Selenium:
pip3 install selenium
Then get a driver e.g. https://sites.google.com/a/chromium.org/chromedriver/downloads (if you are on Windows or Mac you can get a headless version of Chrome - Canary if you like) put the driver in your path.
from bs4 import BeautifulSoup
from selenium import webdriver
import time
browser = webdriver.Chrome()
url = ('https://soundcloud.com/search/sounds?q=f& filter.created_at=last_year&filter.genre_or_tag=hip-hop%20%26%20rap')
browser.get(url)
time.sleep(5)
# To make it load more scroll to the bottom of the page (repeat if you want to)
browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(5)
html_source = browser.page_source
browser.quit()
soup = BeautifulSoup(html_source, 'html.parser')
for id in soup.findAll("a", {"class" : "sound__coverArt"}):
print (id.get('href'))
Outputs:
/tee-grizzley/from-the-d-to-the-a-feat-lil-yachty
/empire/fat-joe-remy-ma-all-the-way-up-ft-french-montana
/tee-grizzley/first-day-out
/21savage/feel-it
/pluggedsoundz/famous-dex-geek-1
/rodshootinbirds/fairytale-x-rod-da-god
/chancetherapper/finish-line-drown-feat-t-pain-kirk-franklin-eryn-allen-kane-noname
/alkermith/future-low-life-ft-the-weeknd-evol
/javon-woodbridge/fabolous-slim-thick
/hamburgerhelper/feed-the-streets-prod-dequexatron-1000
/rob-neal-139819089/french-montana-lockjaw-remix-ft-gucci-mane-kodak-black
/pluggedsoundz/famous-dex-energy
/ovosoundradiohits/future-ft-drake-used-to-this
/pluggedsoundz/famous
/a-boogie-wit-da-hoodie/fucking-kissing-feat-chris-brown
/wavey-hefner/foreign
/jalensantoy/foreplay
/yvng_swag/fall-in-luv
/rich-the-kid/intro-prod-by-lab-cook
/empire/fat-joe-remy-ma-money-showers-feat-ty-dolla-ign