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

基于C# Selenium切换谷歌账号时导航失败问题及代码优化方案

问题与解决方案:C# Selenium切换谷歌账号无法导航及执行上传

问题描述

使用C#结合Selenium切换谷歌账号时,账号能成功打开,但无法导航到YouTube Studio目标URL,后续视频上传操作(调用await VideoYukle(driver, token);)也无法执行。需求是依次打开各个谷歌配置文件账号,导航到指定URL并完成视频上传交易。

现有代码问题分析

  • 固定远程调试端口冲突:所有实例共用9222端口,多实例启动时会触发端口占用,导致后续浏览器实例无法正常初始化
  • 硬等待不可靠:Task.Delay(2000)是固定时长等待,无法适配不同环境的浏览器启动速度
  • 页面加载判断不严谨:仅通过URL包含字符串判断页面加载,可能遇到重定向或页面未完全渲染就触发后续操作
  • MessageBox阻塞自动化流程:弹窗会中断自动化执行,必须手动点击才能继续,不符合无人值守需求
  • 方法返回值语法错误:OpenUrlInChromeProfile声明返回string[]但实际无返回内容

修改后的完整代码

// YouTube Studio 地址
private string youtubeStudioUrl = "https://studio.youtube.com";

// 查找所有配置文件目录并逐个调用OpenUrlInChromeProfile
public async Task OpenYouTubeStudiosAsync(CancellationToken token)
{
    string userDataPath = @"C:\Users\fehmi\AppData\Local\Google\Chrome\User Data"; // 用户数据目录
    string[] profileDirectories = Directory.GetDirectories(userDataPath, "Profile *"); // 获取所有配置文件

    foreach (string profileDir in profileDirectories)
    {
        if (token.IsCancellationRequested)
            break; // 若请求取消则终止循环

        try
        {
            string profileName = new DirectoryInfo(profileDir).Name; // 获取配置文件名
            Console.WriteLine($"正在处理配置文件: {profileName}");

            // 为每个配置文件打开YouTube Studio
            await OpenUrlInChromeProfile(profileName, token);
            // 可选:不同实例间添加间隔,避免资源占用过高
            await Task.Delay(1000, token);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"处理配置文件 {profileName} 时出错: {ex.Message}");
        }
    }
}

private async Task OpenUrlInChromeProfile(string profileName, CancellationToken token)
{
    // 为每个实例分配唯一远程调试端口,避免冲突
    int debugPort = 9222 + Array.IndexOf(Directory.GetDirectories(@"C:\Users\fehmi\AppData\Local\Google\Chrome\User Data", "Profile *"), profileName);

    // 配置ChromeOptions
    ChromeOptions options = new ChromeOptions();
    options.AddArgument($"--user-data-dir={@"C:\Users\fehmi\AppData\Local\Google\Chrome\User Data"}");
    options.AddArgument($"--profile-directory={profileName}");
    options.AddArgument($"--remote-debugging-port={debugPort}"); // 动态分配端口
    options.AddArgument("--start-maximized"); // 最大化窗口,避免元素定位问题

    // 通过ChromeDriver启动Chrome
    using (IWebDriver driver = new ChromeDriver(options))
    {
        try
        {
            // 等待浏览器启动并可交互,替代硬等待
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));
            wait.Until(d => d.ExecuteScript("return document.readyState").ToString() == "complete");

            // 导航到YouTube Studio
            driver.Navigate().GoToUrl(youtubeStudioUrl);
            Console.WriteLine($"正在为配置文件 {profileName} 导航到 {youtubeStudioUrl}");

            // 等待页面完全加载,同时监听取消令牌
            wait.Until(d => 
                d.Url.StartsWith("https://studio.youtube.com") && 
                d.ExecuteScript("return document.readyState").ToString() == "complete");
            Console.WriteLine($"配置文件 {profileName} 的页面已加载完成。");

            // 执行视频上传操作,传入取消令牌
            await VideoYukle(driver, token);
        }
        catch (WebDriverException ex)
        {
            Console.WriteLine($"配置文件 {profileName} WebDriver错误: {ex.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"配置文件 {profileName} 通用错误: {ex.Message}");
        }
    }
}

// 示例VideoYukle方法(需根据实际逻辑实现)
private async Task VideoYukle(IWebDriver driver, CancellationToken token)
{
    // 这里添加实际的视频上传逻辑,例如点击上传按钮、选择文件等
    // 示例:等待上传按钮并点击
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
    var uploadButton = wait.Until(d => d.FindElement(By.XPath("//*[@aria-label='上传']")));
    uploadButton.Click();
    await Task.Delay(5000, token); // 模拟上传等待,实际需根据页面状态判断
    Console.WriteLine("视频上传操作执行完成");
}

关键修改说明

  • 动态分配远程调试端口:每个浏览器实例使用不同端口,避免多实例启动时的端口冲突问题
  • 替换硬等待为显式等待:使用WebDriverWait等待文档加载完成,确保浏览器和页面真正就绪后再执行操作
  • 移除MessageBox弹窗:改用控制台输出日志,避免阻塞自动化流程,适合无人值守场景
  • 修复方法返回值错误:将OpenUrlInChromeProfile的返回值改为Task,符合异步方法规范
  • 增强页面加载判断逻辑:同时验证URL前缀和文档就绪状态,确保页面完全加载后再执行上传操作
  • 添加取消令牌到所有异步操作:确保在请求取消时,所有等待和异步操作能及时终止

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 02:50:56