I am trying to automate a website with selenium to download an excel file. I have the following HTML for the button:
<div class="row ng-scope" ng-if="!model.update_rota">
<div class="col-sm-12 hidden-xs hidden-sm">
<button type="button" class="btn btn-success btn-block" title="יצא לאקסל" ng-click="excelRota();" ng-disabled="!model.rota.id || model.rotaLoading">
<i class="fa fa-file-excel-o fa-lg"></i> אקסל
</button>
</div>
<!-- ngIf: model.features.reports.attributes.availability_shifts_report.value == 'True' -->
<!-- ngIf: model.features.tips.is_active && model.features.tips.attributes.tips_calculate.value == 'True' -->
<div class="col-sm-12">
<div class="btn-group btn-block visible-xs-block visible-sm-block">
<button type="button" class="btn btn-info btn-block dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" ng-disabled="model.rotaLoading">
<i class="fa fa-bars fa-lg"></i> אפשרויות
</button>
<ul class="dropdown-menu">
<!-- ngIf: model.features.tips.is_active && model.features.tips.attributes.tips_calculate.value == 'True' -->
<li ng-class="{'disabled': !model.rota.id}" class="" style=""><a href="#" ng-click="excelRota();"><i class="fa fa-file-excel-o text-success"></i> יצא סידור לאקסל</a></li>
<!-- ngIf: model.features.reports.attributes.availability_shifts_report.value == 'True' -->
</ul>
</div>
</div>
</div>
I have tried clicking on the button with the following find element by class:
driver.find_element_by_class_name('btn btn-success btn-block').click()
The error message I get is:
selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".btn btn-success btn-block"}
I have also tried:
driver.execute_script("excelRota();")
And received the following error:
selenium.common.exceptions.JavascriptException: Message: javascript error: excelRota is not defined
I have logged in this website successfully and worked my way around the site up until the excel file page, but I can’t figure out how to click this button.
I have written my script as headless chrome if it makes any difference.
Update:
This is my whole code:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
import os
import time
import pandas as pd
from tkinter import *
import datetime
excel_shifts_download_url = 'https://app.shiftorganizer.com/excel/rota/125102/?'
download_dir = "C:\Users\Documents\Python Scripts\projects\shifts_script"
driver_path = "C:\Users\Documents\Python Scripts\projects\shifts_script\chromedriver.exe"
shiftorgnizer_login_url = 'https://app.shiftorganizer.com/login/?lang=he&previous=homepage&greeting=true'
# enabling headless chrome
def setting_chrome_options():
chrome_options = Options()
chrome_options.add_argument("--headless")
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-gpu')
chrome_options.add_argument('--disable-software-rasterizer')
return chrome_options
driver = webdriver.Chrome(executable_path=driver_path, options=setting_chrome_options())
# Login GUI
def login_gui():
root = Tk()
root.title('Shifter')
root.geometry("250x130")
root.focus_force()
global entry_company_id
global entry_username
global entry_password
global checkbox_var
checkbox_var = IntVar()
# Text near text box username & password
label_company_id = Label(root, text='Company ID')
label_username = Label(root, text='Username')
label_password = Label(root, text='Password')
# Textbox for username & password
entry_company_id = Entry(root)
entry_username = Entry(root)
entry_password = Entry(root)
# Positioning of text
label_company_id.grid(row=0, sticky=E)
label_username.grid(row=1, sticky=E)
label_password.grid(row=2, sticky=E)
# Positioning of textboxes
entry_company_id.grid(row=0, column=1)
entry_username.grid(row=1, column=1)
entry_password.grid(row=2, column=1)
# Login button
root.bind('<Return>', site_login)
b = Button(root, text='Login', command=site_login)
b.grid(row=4, column=1)
checkbox = Checkbutton(root, text='Get next week Shifts', variable=checkbox_var)
checkbox.grid(row=3, column=1)
root.mainloop()
current_day_date = datetime.date.today()
next_sunday_date = current_day_date + datetime.timedelta( (6 - current_day_date.weekday()) % 7 )
# Site login with user's credentials
def site_login():
global company_id
global username
global password
username = str(entry_username.get())
password = str(entry_password.get())
company_id = str(entry_company_id.get())
driver.get (shiftorgnizer_login_url)
driver.implicitly_wait(20)
driver.find_element_by_id('company').send_keys(company_id)
driver.find_element_by_id ('username').send_keys(username)
driver.find_element_by_id ('password').send_keys(password)
driver.find_element_by_id('log-in').click()
# downloading shifts file
enable_download(driver)
WebDriverWait(driver, 10).until(EC.title_contains("בית | ShiftOrganizer"))
driver.get('https://app.shiftorganizer.com/app/rota')
WebDriverWait(driver, 10).until(EC.title_contains("סידור | ShiftOrganizer"))
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,".btn.btn-success.btn-block"))).click()
# if checkbox_var.get() == 0:
# driver.find_element_by_class_name('col-sm-12 hidden-xs hidden-sm').click()
# elif checkbox_var.get() == 1:
# driver.get('https://app.shiftorganizer.com/app/rota'+'?date='+next_sunday_date)
# WebDriverWait(driver, 10).until(EC.title_contains("סידור | ShiftOrganizer"))
# driver.get(excel_shifts_download_url)
isFileDownloaded()
# permission to download file via Selenium
def enable_download(driver):
driver.command_executor._commands["send_command"] = ("POST", '/session/$sessionId/chromium/send_command')
params = {'cmd':'Page.setDownloadBehavior', 'params': {'behavior': 'allow', 'downloadPath': download_dir}}
driver.execute("send_command", params)
# check if file has been downloaded
def isFileDownloaded():
file_path = download_dir+"\schedule.xlsx"
while not os.path.exists(file_path):
time.sleep(1)
if os.path.isfile(file_path):
print("File Downloaded Successfully")
login_gui()
When I disable headless chrome option the file is being downloaded
Advertisement
Answer
find_element_by_class_name()
doesn’t accepts multiple class name. Instead you can use css selector
.
To avoid synchronization issue Induce WebDriverWait()
and wait for element_to_be_clickable()
and following css selector.
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,".btn.btn-success.btn-block"))).click()
You need to import below libraries.
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
Reference link for css selector