繁体   English   中英

JavascriptException:消息:javascript 错误:无法读取属性“单击”的未定义错误执行 JavaScript 到 Python ZC49DFB575F06FCBB50DFB575F06FCBB50DFB575CA

[英]JavascriptException: Message: javascript error: Cannot read property 'click' of undefined error executing JavaScript through Python Selenium

我有以下代码,我在其中输入页面并搜索产品,我想执行 JavaScript 代码

from selenium import webdriver
from getpass import getpass
#-------------------------------------------PRODUCT SEARCH-----------------------------------------------------------------------------------
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument("--disable-blink-features=AutomationControlled")

driver = webdriver.Chrome("C:\\Users\\stbaz\\Documents\\Python\\ChromeTools\\chromedriver.exe", options=options)
driver.get("https://www.innvictus.com/")
product_textbox = driver.find_element_by_id("is-navigation__search-bar__input")
product_textbox.send_keys("FW7093")
product_textbox.submit()
#------------------------------------------PRODUCT SEARCH END--------------------------------------------------------------------------------------

driver.implicitly_wait(5)
js='javascript:document.getElementsByClassName("buy-button buy-button--sticky buy-button--buy-now visible-xs visible-sm")[1].click();window.open("/checkout")'
driver.execute_script(js)

但我收到以下错误

selenium.common.exceptions.JavascriptException: Message: javascript error: Cannot read property 'click' of undefined

我可以在 chrome 中手动运行该代码,我使用书签,但我想在 Python 中运行它,我做错了什么?

主要得到一个错误“无法读取未定义的属性'click'”是如果在 DOM 中找不到选择器或 class。 我相信如果 JavaScript 在标记/DOM 中找不到选择器或者它不存在,就会发生错误。 也许你应该试试js='javascript:document.getElementsByClassName("buy-button buy-button--sticky buy-button--buy-now visible-xs visible-sm").click();window.open("/checkout")'没有索引。 在 Selenium 中使用 Java 脚本执行程序时检查无法读取未定义的属性“单击”它可能会有所帮助

此错误消息...

selenium.common.exceptions.JavascriptException: Message: javascript error: Cannot read property 'click' of undefined

...意味着无法执行click()方法,因为WebElement尚未在DOM 树中完全呈现,并且该元素仍然是未定义的元素。


解决方案

要执行 JavaScript,您需要为visibility_of_all_elements_located()诱导WebDriverWait ,您可以使用以下任一定位器策略

  • 使用CSS_SELECTOR

     WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.CSS_SELECTOR, ".buy-button.buy-button--sticky.buy-button--buy-now.visible-xs.visible-sm"))) driver.execute_script("var x= document.getElementsByClassName('buy-button buy-button--sticky buy-button--buy-now visible-xs visible-sm')[0];"+"x.click();")
  • 使用XPATH

     WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, "//*[@class='buy-button buy-button--sticky buy-button--buy-now visible-xs visible-sm']"))) driver.execute_script("var x= document.getElementsByClassName('buy-button buy-button--sticky buy-button--buy-now visible-xs visible-sm')[0];"+"x.click();")
  • 注意:您必须添加以下导入:

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

因此,我在不使用JavaScript的情况下包含了主程序; 但是,在主程序参考下,我也包含了使用JavaScript的方法。

为了在没有 JS 的情况下实现这个解决方案,我使用xpath来验证页面加载成功。 然后,在那之后,我找到了搜索按钮的xpath

//nav[@class='is-navigation']//span[contains(@class, 'search-btn')]

一旦我为此发现了xpath ,我单击了搜索按钮,然后创建了一种方法来搜索特定产品。 在我的例子中,我以“匡威”鞋为例。

def search_for_text(driver : ChromeDriver, text : str):
    driver.find_element(By.XPATH, "//form[@id='formSearch']//input[contains(@data-options, 'SearchBox')]").send_keys(text)
    time.sleep(2)
    if driver.find_element(By.XPATH, "//form[@id='formSearch']//input[contains(@data-options, 'SearchBox')]").get_attribute('value').__len__() != text.__len__():
        raise Exception("Failed to populate our search textbox")
    else:
        driver.find_element(By.XPATH, "//form[@id='formSearch']//input[contains(@data-options, 'SearchBox')]").send_keys(Keys.RETURN)
        time.sleep(2)
        wait_displayed(driver, "//div[@class='is-pw__products']//div[contains(@class, 'products-list')]", 30)
        print(f'Your search for {text} was successful')

在该方法中,您会看到我使用wait_displayed来验证我的产品列表是否正确显示。

主程序 - 供参考

from selenium import webdriver
from selenium.webdriver.chrome.webdriver import WebDriver as ChromeDriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait as DriverWait
from selenium.webdriver.support import expected_conditions as DriverConditions
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.keys import Keys
import time


def get_chrome_driver():
    """This sets up our Chrome Driver and returns it as an object"""
    path_to_chrome = "F:\Selenium_Drivers\Windows_Chrome87_Driver\chromedriver.exe"
    chrome_options = webdriver.ChromeOptions() 
    
    # Browser is displayed in a custom window size
    chrome_options.add_argument("window-size=1500,1000")
    
    return webdriver.Chrome(executable_path = path_to_chrome,
                            options = chrome_options)

    
def wait_displayed(driver : ChromeDriver, xpath: str, int = 5):
    try:
         DriverWait(driver, int).until(
            DriverConditions.presence_of_element_located(locator = (By.XPATH, xpath))
        )
    except:
        raise WebDriverException(f'Timeout: Failed to find {xpath}')
    
    
def is_displayed(driver : ChromeDriver, xpath: str, int = 5):
    try:
         webElement = DriverWait(driver, int).until(
            DriverConditions.presence_of_element_located(locator = (By.XPATH, xpath))
        )
         return True if webElement != None else False
    except:
        return False
    
    
def click_search(driver : ChromeDriver):
    driver.find_element(By.XPATH, "//nav[@class='is-navigation']//span[contains(@class, 'search-btn')]").click()
    time.sleep(2)
    if is_displayed(driver, "//form[@id='formSearch']//input[contains(@data-options, 'SearchBox')]") == False:
        raise Exception("Failed to click our search button")
    else:
        print('You clicked the Search Button Successfully')
    
    
def search_for_text(driver : ChromeDriver, text : str):
    driver.find_element(By.XPATH, "//form[@id='formSearch']//input[contains(@data-options, 'SearchBox')]").send_keys(text)
    time.sleep(2)
    if driver.find_element(By.XPATH, "//form[@id='formSearch']//input[contains(@data-options, 'SearchBox')]").get_attribute('value').__len__() != text.__len__():
        raise Exception("Failed to populate our search textbox")
    else:
        driver.find_element(By.XPATH, "//form[@id='formSearch']//input[contains(@data-options, 'SearchBox')]").send_keys(Keys.RETURN)
        time.sleep(2)
        wait_displayed(driver, "//div[@class='is-pw__products']//div[contains(@class, 'products-list')]", 30)
        print(f'Your search for {text} was successful')
        


# Gets our chrome driver and opens our site
chrome_driver = get_chrome_driver()
chrome_driver.get("https://www.innvictus.com/")
wait_displayed(chrome_driver, "(//nav[@class='is-navigation']//div[contains(@class, 'desktop-menu')]//a[contains(@href, 'lanzamientos')])[1]")
wait_displayed(chrome_driver, "//div[@class='content-page']//div[@class='scrolling-wrapper-flexbox']")
wait_displayed(chrome_driver, "//nav[@class='is-navigation']//span[contains(@class, 'search-btn')]")
click_search(chrome_driver)
search_for_text(chrome_driver, "Converse")
chrome_driver.quit()
chrome_driver.service.stop()

使用 JAVASCRIPT 单击搜索按钮的命令

jsText = "document.querySelector('nav').querySelector('div .is-navigation__main').querySelector('div .is-navigation__main__right').querySelector('span').click()"
driver.execute_script(jsText)

方法

def click_search_using_javaScript(driver : ChromeDriver):
    jsText = "document.querySelector('nav').querySelector('div .is-navigation__main').querySelector('div .is-navigation__main__right').querySelector('span').click()"
    driver.execute_script(jsText)
    time.sleep(2)
    if is_displayed(driver, "//form[@id='formSearch']//input[contains(@data-options, 'SearchBox')]") == False:
        raise Exception("Failed to click our search button")
    else:
        print('You clicked the Search Button Successfully')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM