C# Selenium操作指南,关闭黑色CMD窗口/禁用图片/隐藏浏览器等,更新待续....

1.用到的程序包(NuGet搜这两个即可,自己看版本)


2.配置部分:

public void StartBrowser()
{
    ChromeOptions options = new ChromeOptions();
    
    // 指定缓存目录
    string cacheDirectory = System.Environment.CurrentDirectory + @"\cache";
    if (!Directory.Exists(cacheDirectory))
    {
        Directory.CreateDirectory(cacheDirectory);
    }
    options.AddArgument($"--user-data-dir={cacheDirectory}");
    //隐身模式(无痕模式)
    options.AddArgument("--incognito");
    //取消 chrome正受到自动测试软件的控制的信息栏
    options.AddExcludedArgument("enable-automation");
    options.AddAdditionalChromeOption("useAutomationExtension", false);
    // 设置窗口大小和位置
    options.AddArgument("window-size=1280,960");  // 设置窗口大小
    options.AddArgument("window-position=0,0"); // 设置窗口位置
    // 防止检测为自动化操作
    options.AddArgument("--disable-blink-features=AutomationControlled");
    options.AddArgument("--disable-infobars");
    options.AddArgument("--disable-extensions");
    options.AddUserProfilePreference("profile.default_content_setting_values.notifications", 2);
    //禁用浏览器的保存密码选项
    options.AddUserProfilePreference("credentials_enable_service", false);
    //禁用浏览器弹窗(貌似不管用)
    options.AddUserProfilePreference("profile.default_content_setting_values.notifications", 2);

    //-------------------------------
    // 不显示浏览器
    //options.AddArgument("--headless");
    // GPU加速可能会导致Chrome出现黑屏及CPU占用率过高,所以禁用
    //options.AddArgument("--disable-gpu");
    // 伪装user-agent
    //options.AddArgument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.6261.95 Safari/537.36");

    // 禁用图片
    //options.AddUserProfilePreference("profile.default_content_setting_values.images", 2);
    //指定浏览器配置目录
    //string str = System.Environment.CurrentDirectory + "\\selenium\\AutomationProfile";
    //options.AddArgument(@"--user-data-dir=" + str);

    //指定使用本地浏览器
    //options.BinaryLocation = browserAddress;
    //options.BinaryLocation = "D:\\develop\\360浏览器\\360se6\\Application\\360se.exe";
    //-------------------------------

    ChromeDriverService driverService = ChromeDriverService.CreateDefaultService();
    driverService.HideCommandPromptWindow = true;//关闭黑色cmd窗口

    IWebDriver webDriver = new ChromeDriver(driverService, options);

    //Selenium事件驱动
    eventDriver = new EventFiringWebDriver(webDriver);
    // 设置页面加载超时时间
    eventDriver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(20);
    
    //如果查找元素在10S内还没有找到.如果你每次点击元素前都使用了 WebDriverWait 来显式等待元素变得可点击,那么不需要再设置隐式等待 (ImplicitWait)。此时,你可以依赖 WebDriverWait 来处理等待逻辑,这样代码更清晰,也避免了不必要的等待时间叠加。如果你希望为所有查找操作设置一个默认的全局等待时间,可以设置 ImplicitWait,但在这种情况下,显式等待应当仅在特定情况下使用,以避免两者的等待时间相互冲突。
    //eventDriver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(10);
    
    //为Selenium添加事件
    eventDriver = new EventFiringWebDriver(webDriver);
    //eventDriver.Navigating += EventDriver_Navigating;//导航前
    eventDriver.Navigated += EventDriver_Navigated;//导航后

    //string url = "https://www.baidu.com";
    string url = "https://www.google.com/";
    try
    {
        eventDriver.Navigate().GoToUrl(url);
    }
    catch (WebDriverTimeoutException e)
    {
        // 页面加载超时,停止加载
        IJavaScriptExecutor jsExecutor = (IJavaScriptExecutor)eventDriver;
        jsExecutor.ExecuteScript("window.stop();");
    }
    catch (Exception ex)
    {
        SetLog($"{DateTime.Now} 发生异常: {ex.GetType().Name}\r\n{ex.Message}\r\n{ex.StackTrace}");
    }

    // 延时等待页面加载
    Thread.Sleep(1000);

    // 等待元素出现并点击
    wait = new WebDriverWait(eventDriver, TimeSpan.FromSeconds(10));

    try
    {
        IWebElement element = wait.Until(d => d.FindElement(By.CssSelector("a.gb_va.gb_nd.gb_ed.gb_9d")));
        element.Click();
    }
    catch (WebDriverTimeoutException e)
    {
        var str = string.Format("异常类型:{0}\r\n异常消息:{1}\r\n异常信息:{2}\r\n",
            e.GetType().Name, e.Message, e.StackTrace);
        SetLog($"{DateTime.Now} 等待元素超时,未找到相应的 a 元素" + str);
    }
    catch (NoSuchElementException)
    {
        SetLog($"{DateTime.Now} 元素未找到");
    }
    catch (Exception ex)
    {
        SetLog($"{DateTime.Now} 发生异常: {ex.Message}");
    }


}

↓↓↓↓↓↓↓↓需要什么事件,这边自己慢慢找↓↓↓↓↓↓↓↓

提示:这边的事件只有在使用eventDriver的进行的操作才会触发,如果你是手动操作的,那么这边的事件是不会被触发的


3.元素操作部分

点击元素

/// <summary>
/// 点击元素
/// </summary>
/// <param name="by"></param>
/// <param name="timeoutInSeconds">等待默认20秒</param>
/// <returns></returns>
public bool ClickElement(By by,int timeoutInSeconds = 20)
{
    try
    {
        // 获取当前时间
        var endTime = DateTime.Now.AddSeconds(timeoutInSeconds);

        while (isRun && DateTime.Now < endTime)
        {
            try
            {
                // 查找元素
                IWebElement element = eventDriver.FindElement(by);

                // 检查元素是否显示并可交互
                if (element.Displayed && element.Enabled)
                {
                    element.Click();
                    return true; // 点击成功
                }
            }
            catch (NoSuchElementException)
            {
                //SetLog("元素可能还未加载,继续等待");
            }
            catch (ElementClickInterceptedException)
            {
                SetLog($"{by.ToString()} 点击被另一个元素挡住,继续尝试");
            }
            catch (StaleElementReferenceException)
            {
                SetLog($"{by.ToString()} 元素不再是当前文档中的一部分,继续尝试");
            }

            // 等待一段时间后再尝试
            Sleep(0.5);
        }

        // 超时后仍未能成功点击
        return false;
    }
    catch (WebDriverException ex)
    {
        SetLog($"{by.ToString()} WebDriver 错误: {ex.Message}");
        return false;
    }
    catch (Exception ex)
    {
        SetLog($"{by.ToString()} 发生未知错误: {ex.Message}");
        return false;
    }
}

模拟鼠标在指定元素悬停

//模拟鼠标在指定元素悬停
Actions action = new Actions(eventDriver);
var mouserOverlogin = action.MoveToElement(eventDriver.FindElement(By.Id("js_N_nav_login_title"))).Build(); ;
mouserOverlogin.Perform();

如果要点击的元素被其他元素遮挡,报异常,可以用这种方法来点击

var element = webDriver.FindElement(By.Id("mybutton"));  //点击写信
((IJavaScriptExecutor)webDriver).ExecuteScript(@"arguments[0].click()", element);

执行JS(将滚动条拉到底部):

//老版执行JS方法
//((IJavaScriptExecutor)webDriver).ExecuteScript("window.scrollTo(0, document.body.scrollHeight)");
//事件驱动执行JS方法
eventDriver.ExecuteScript("window.scrollTo(0, document.body.scrollHeight)");

获取标签(以多Class为例):

ReadOnlyCollection<IWebElement> elements = eventDriver.FindElements(By.CssSelector("[class='item goWork']"));

切换标签页面(eventDriver无法监控当前是在哪个标签页,只能自己SwitchTo)

foreach (string eventDriverWindowHandle in eventDriver.WindowHandles)
{
    eventDriver.SwitchTo().Window(eventDriverWindowHandle);
    if (eventDriver.Title == "云筑优选-商品详情")
    {
        downImg();
        break;
    }
}

退出同时关闭驱动

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // 仅在用户关闭窗口时进行提示
    if (e.CloseReason == CloseReason.UserClosing)
    {
        // 显示退出确认对话框
        DialogResult result = MessageBox.Show("确认退出吗?", "提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Information);
        if (result == DialogResult.OK)
        {
            // 执行退出前的清理工作
            isRun = false;

            if (eventDriver != null)
            {
                // 关闭浏览器并释放资源
                eventDriver.Quit();
                eventDriver.Dispose();
                Thread.Sleep(100); // 确保驱动已关闭
            }
            
            //CMD删除缓存文件夹
            string cache = System.Environment.CurrentDirectory + @"\cache";
            List<string> list = new List<string>() { $"rmdir /s /q \"{cache}\"" };
            ExecutionCMDOrders(list, false);

            // 允许应用程序退出并退出应用程序
            e.Cancel = false;
            Application.Exit(); // 确保应用程序退出
        }
        else
        {
            // 取消窗口关闭操作
            e.Cancel = true;
        }
    }
    else
    {
        // 对于非用户触发的关闭(如内部调用 Application.Exit()),允许退出
        e.Cancel = false;
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值