You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VB.NET中Selenium WebDriver的NoSuchElementException问题求助

VB.NET Selenium WebDriver YouTube广告跳过异常问题

问题描述

在VB.NET的Selenium WebDriver项目中模拟YouTube视频播放操作:播放视频约40秒,若视频前有广告则等待10秒点击“Skip ad”按钮跳过,无广告则直接播放。但无广告场景下程序报错,无法定位跳过广告按钮,尝试用Try-Catch捕获NoSuchElementException未达到预期效果。

环境信息

  • 操作系统:Windows 11
  • Edge浏览器版本:128.0.2739.42
  • Edge WebDriver版本:128.0.2739.42

原代码片段

Imports System.Threading
Imports OpenQA.Selenium
Imports OpenQA.Selenium.Edge
Imports OpenQA.Selenium.Support.UI

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ' Setup EdgeOptions
        Dim options As New EdgeOptions()
        options.AddArgument("--user-data-dir=C:\Users\jasonfan\AppData\Local\Microsoft\Edge\User Data")
        options.AddArgument("--remote-debugging-pipe")
        options.AddArgument("--allow-running-insecure-content")
        options.AddArgument("log-level=3")

        Dim driver As IWebDriver = New EdgeDriver(options)

        Try
            Dim index As Integer = 0

            Do While index <= 5
                'Navigate to the URL of a youtube video
                '****This is just a testing example. It could be any youtube video.****
                driver.Navigate().GoToUrl("https://www.youtube.com/watch?v=gnpyIbK-Y78")

                ' Wait for the ad skip button to appear (if present)
                Dim adSkipButtonFound As Boolean = False
                Try
                    Dim wait As New WebDriverWait(driver, TimeSpan.FromSeconds(10))
                    wait.IgnoreExceptionTypes(GetType(NoSuchElementException))
                    Dim adSkipButton As IWebElement = wait.Until(Function(d) d.FindElement(By.CssSelector(".ytp-skip-ad-button")))
                    adSkipButtonFound = True
                    ' If ad skip button appears, wait for 10 seconds and click it
                    Thread.Sleep(10000)
                    adSkipButton.Click()
                Catch ex As WebDriverTimeoutException
                    ' No ad skip button present, let the video play
                    MessageBox.Show("No ad skip button found, letting video play.")
                End Try

                ' Wait for the video to finish playing (approximately 40 seconds)
                Thread.Sleep(40000) ' Adjusted to 40 seconds

                index += 1
            Loop
        Catch ex As WebDriverException
            MessageBox.Show("Error: " & ex.Message)
        Catch ex As Exception
            MessageBox.Show("Error: " & ex.Message)
        Finally
            ' Clean up
            driver.Quit()
        End Try
    End Sub

    ' Define a function to get a random delay
    Private Function RandomDelay() As Integer
        Dim rnd As New Random()
        Return rnd.Next(1000, 3000) ' Random delay between 1 and 2 seconds
    End Function
End Class

报错信息

OpenQA.Selenium.NoSuchElementException: 'no such element: Unable to locate element: {"method":"css selector","selector":".ytp-skip-ad-button"}
  (Session info: MicrosoftEdge=128.0.2739.63); For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors#no-such-element-exception

问题分析与解决方案

核心问题

原代码中使用FindElement查找按钮,该方法在元素不存在时会直接抛出NoSuchElementException,即使设置了wait.IgnoreExceptionTypes,也无法完全避免异常触发——因为Until方法需要返回非空元素,无广告场景下一直返回null,最终导致异常未被预期的WebDriverTimeoutException捕获。

修改方案

改用FindElements(返回元素列表,不存在时返回空列表而非抛出异常)结合WebDriverWait判断元素是否存在,替换原有的广告检查逻辑:

' Wait for up to 10 seconds to check for ad skip button
Dim wait As New WebDriverWait(driver, TimeSpan.FromSeconds(10))
wait.IgnoreExceptionTypes(GetType(StaleElementReferenceException))

' Use FindElements to avoid throwing exception when element doesn't exist
Dim adSkipButtons As ReadOnlyCollection(Of IWebElement) = wait.Until(Function(d) 
    Dim elements = d.FindElements(By.CssSelector(".ytp-skip-ad-button"))
    ' Return elements only if found, else null to continue waiting
    Return If(elements.Count > 0, elements, Nothing)
End Function)

If adSkipButtons IsNot Nothing AndAlso adSkipButtons.Count > 0 Then
    ' Wait 10 seconds before skipping ad
    Thread.Sleep(10000)
    adSkipButtons(0).Click()
    MessageBox.Show("Ad skipped successfully.")
Else
    MessageBox.Show("No ad skip button found, letting video play.")
End If

额外优化建议

  1. 避免硬等待:用WebDriverWait结合JavaScript获取视频播放状态替代Thread.Sleep,比如判断视频播放时长:
    ' Wait for video to play for 40 seconds
    Dim videoWait As New WebDriverWait(driver, TimeSpan.FromSeconds(45))
    videoWait.Until(Function(d)
        Dim currentTime As Double = CDbl(d.ExecuteScript("return document.querySelector('video').currentTime;"))
        Return currentTime >= 40
    End Function)
    
  2. 检查广告iframe:部分YouTube广告可能嵌套在iframe中,需要先切换iframe再查找元素:
    ' Check for ad iframes and switch to them
    Dim adIframes = driver.FindElements(By.CssSelector("iframe[src*='googleads']"))
    For Each iframe In adIframes
        driver.SwitchTo().Frame(iframe)
        Dim skipBtn = driver.FindElements(By.CssSelector(".ytp-skip-ad-button"))
        If skipBtn.Count > 0 Then
            Thread.Sleep(10000)
            skipBtn(0).Click()
            ' Switch back to main page after handling
            driver.SwitchTo().DefaultContent()
            Exit For
        End If
        driver.SwitchTo().DefaultContent()
    Next
    
  3. 验证选择器有效性:通过浏览器开发者工具确认跳过按钮的最新CSS类名,YouTube可能会更新元素样式,比如当前部分场景下按钮类名为.ytp-skip-ad-button-modern。

内容的提问来源于stack exchange,提问作者Jason Fan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 21:05:12