【问题标题】:Selenium click on ng-click buttonSelenium 点击 ng-click 按钮
【发布时间】:2020-11-19 22:35:03
【问题描述】:

我正在尝试使用 selenium 自动化网站以下载 excel 文件。 我有以下 HTML 按钮:

<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>&nbsp;אקסל
                </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>&nbsp;אפשרויות
                  </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>&nbsp;יצא סידור לאקסל</a></li>
                    <!-- ngIf: model.features.reports.attributes.availability_shifts_report.value == 'True' -->
                  </ul>
                </div>
              </div>
            </div>

我已尝试按类单击具有以下查找元素的按钮:

driver.find_element_by_class_name('btn btn-success btn-block').click()

我得到的错误信息是:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":".btn btn-success btn-block"}

我也试过了:

driver.execute_script("excelRota();")

并收到以下错误:

selenium.common.exceptions.JavascriptException: Message: javascript error: excelRota is not defined

我已成功登录该网站并在该网站上工作,直到出现 excel 文件页面,但我不知道如何单击此按钮。

如果有任何区别,我已将脚本编写为 headless chrome。

更新:

这是我的全部代码:

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()

当我禁用 headless chrome 选项时,正在下载文件

【问题讨论】:

  • 添加你得到的错误信息?

标签: python angularjs selenium xpath css-selectors


【解决方案1】:

find_element_by_class_name() 不接受多个类名。相反,您可以使用css selector

避免同步问题诱导WebDriverWait()并等待element_to_be_clickable()并关注css selector.

WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.CSS_SELECTOR,".btn.btn-success.btn-block"))).click()

您需要导入以下库。

from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

css selector的参考链接

【讨论】:

  • 我已经尝试并收到以下错误:“ selenium.common.exceptions.TimeoutException: Message:” 没有任何进一步的细节
  • 当我删除无头 chrome 选项时,它会下载文件。这可能是什么原因?
  • @nomno :对于无头浏览器,您需要指定窗口大小。 chrome_options = webdriver.ChromeOptions()chrome_options.add_argument('--headless')chrome_options.add_argument('window-size=1920x1080');
  • 感谢昆杜克!添加 chrome_options.add_argument('window-size=1920x1080') 似乎可以解决问题。
【解决方案2】:

要点击ng-click 元素,您可以使用以下任一Locator Strategies

  • 使用css_selector

    driver.find_element_by_css_selector("button.btn.btn-success.btn-block[ng-click^='excelRota']>i.fa.fa-file-excel-o.fa-lg").click()
    
  • 使用xpath

    driver.find_element_by_xpath("//button[@class='btn btn-success btn-block' and starts-with(@ng-click, 'excelRota')][contains(., 'אקסל')]").click()
    


理想情况下,由于该元素是Angular 元素,点击该元素需要诱导WebDriverWaitelement_to_be_clickable(),您可以使用以下Locator Strategies 之一:

  • 使用CSS_SELECTOR

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "button.btn.btn-success.btn-block[ng-click^='excelRota']>i.fa.fa-file-excel-o.fa-lg"))).click()
    
  • 使用XPATH:

    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//button[@class='btn btn-success btn-block' and starts-with(@ng-click, 'excelRota')][contains(., 'אקסל')]"))).click()
    
  • 注意:您必须添加以下导入:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-08-01
    • 2021-05-20
    • 2015-09-17
    • 2015-12-06
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多