【问题标题】:selenium.common.exceptions.WebDriverException: Message: unknown error: 'script' must be a string while using execute_script() through Selenium Pythonselenium.common.exceptions.WebDriverException:消息:未知错误:“脚本”必须是字符串,同时通过 Selenium Python 使用 execute_script()
【发布时间】:2018-09-05 14:11:56
【问题描述】:

我在使用 selenium 和 python 时遇到了 browser.execute_script 的问题。我想点击一个元素(下面是 xpath)

"//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]"

我尝试这样做:

navMenu = browser.find_element_by_xpath("//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]")
time.sleep(3)
browser.execute_script(navMenu.click())

它可以工作(因此它会单击所需的元素),但在执行此操作后会立即引发终止脚本的错误:

selenium.common.exceptions.WebDriverException: Message: unknown error: 'script' must be a string

我做错了什么?有没有办法跳过这个错误?谢谢你浪费你的时间来帮助我:)

【问题讨论】:

  • 你正在传递一个函数调用到.execute_script,你需要传递一个字符串,或者直接调用navMenu.click()
  • 只需使用navMenu.click()
  • @RyanWilson 好的,那么正确的做法是什么?
  • navMenu.click()替换browser.execute_script(navMenu.click())
  • @Nihal - 它不起作用 - 它抛出错误“元素不可见”

标签: javascript python selenium selenium-webdriver webdriver


【解决方案1】:

此错误消息...

selenium.common.exceptions.WebDriverException: Message: unknown error: 'script' must be a string

...暗示方法 execute_script() 被调用时使用了错误类型的参数。

execute_script() 方法定义为:

execute_script(script, *args)
    Synchronously Executes JavaScript in the current window/frame.

Where:
    script: The JavaScript to execute
    *args: Any applicable arguments for your JavaScript.

在您的代码试验中,executeScript() 方法将元素的引用作为 arguments[0] 以及要执行的方法(在本例中为 click()),并且引用应该是后提供。所以@Andersson 的解决方案应该有效。

navMenu = browser.find_element_by_xpath("//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]")
browser.execute_script("arguments[0].click()", navMenu)

您可以在What does argument [0] and argument [1] mean in javascriptexecutor in Selenium WebDriver?找到详细讨论


提示您的主要问题是错误element not visible,这意味着以下情况之一:

  • 您正在尝试调用click(),甚至在元素可见/可点击之前
  • 调用click() 时,元素不在Viewport 内。

解决方案

两种可能的解决方案如下:

  • 诱导 WebDriverWait 使 元素可点击 如下:

    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support import expected_conditions as EC
    # other lines of code
    WebDriverWait(driver, 20).until(EC.element_to_be_clickable((By.XPATH, "//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]"))).click()
    
  • 使用executeScript() 方法将元素带入Viewport,然后调用click(),如下所示:

    navMenu = browser.find_element_by_xpath("//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]")
    browser.execute_script("arguments[0].scrollIntoView(true);",navMenu);
    navMenu.click()
    

【讨论】:

  • 非常感谢! WebDriverWait 让元素可点击完美运行。
【解决方案2】:

执行脚本的正确方法是实际编写JavaScript脚本!

selenium 的click() 函数位于您找到的 DOM 元素上,而不是脚本。

正如@Andersson 建议的那样尝试browser.execute_script('arguments[0].click();', navMenu)

我可以看到您添加了 3 秒的睡眠...使用 Selenium 我们通常使用 WebDriverWait 您可以了解有关等待的更多信息 here

如果太复杂,你可以从 driver.implicitly_wait(3) 开始,而不是 sleep。

编辑:

如果元素还没有显示,你可以使用navMenu.is_displayed()

希望对你有所帮助。

【讨论】:

  • 它现在不会导致任何错误,但它实际上并没有点击任何东西。我在browser.execute_script('arguments[0].click();', navMenu) 之后添加了简单的print('ooo'),我在Shell 中得到了ooo,但网站上没有任何反应。感谢您的建议(关于使用 WebDriverWait)。
  • 我的建议是使用等待元素!
  • 我做到了,不知何故它看到了它,但由于它不可见而无法点击它:try:#waits until element is prestent element7_present = EC.presence_of_element_located((By.XPATH, "//*[@id='listFav_FI410_23244709400000_FAGNNURROR_IPOF_APP_P43070_W43070A_CP000A001_40']/table/tbody/tr/td[1]"))#web element identification WebDriverWait(browser, 30).until(element7_present)#max sleep time defined except TimeoutException:#error message definition print('Timed out waiting for page to load')
  • 我知道这听起来很愚蠢 - 等待并且脚本在执行另一个操作时看到它,但由于“元素不可见”而无法执行点击
  • 查看编辑...如果没有帮助,可能是因为该网站是用 Angular 构建的
【解决方案3】:

代替

browser.execute_script(navMenu.click())

试试

browser.execute_script('arguments[0].click();', navMenu)

navMenu.click()

【讨论】:

  • 它现在不会导致任何错误,但它实际上并没有点击任何东西。我在browser.execute_script('arguments[0].click();', navMenu) 之后添加了简单的print('ooo'),我在Shell 中得到了ooo,但网站上没有任何反应。我不能使用 navMenu.click() 因为 webdriver 没有看到元素
  • 共享 HTML 或/和页面 URL
  • 对不起,我不能分享这个链接,因为这个网站包含机密信息(你必须登录,显然我不能给你凭据)。我认为这个问题的根源在于整个网站是由几个 Java Script 脚本生成的。我注意到当我在 shell 中使用 navMenu.click() 时(脚本运行时)它可以工作,但首先我必须实际点击某处有没有办法激活 Java Script?
  • 或者也许有办法告诉脚本在收到我的问题中提到的错误后不要终止进程? Simpy 忽略它并执行另一项任务,因为正如我所说 - 它有效,脚本实际上点击了所需的元素 - 问题是它在它之后立即崩溃(但我想要加载的元素已加载)
  • browser.execute_script(navMenu.click()) 只是执行navMenu.click()。如何调用该方法并不重要。使用 browser.execute_script(navMenu.click()) 毫无意义。尝试实施适当的 ExplicitWait
猜你喜欢
  • 2019-07-21
  • 1970-01-01
  • 2020-10-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-16
  • 1970-01-01
相关资源
最近更新 更多