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

C# Selenium网页爬虫特定代码行持续超时问题求助

问题分析与解决方案

核心问题定位

你遇到的超时本质是异常捕获的死循环中,反复调用driver.Url时,WebDriver与浏览器的会话已处于异常停滞状态——频繁的回退操作可能导致浏览器页面加载卡住,或是WebDriver与浏览器进程的通信阻塞。即便全局设置了长超时,driver.Url属性的读取仍会触发WebDriver内部的HTTP请求,该请求被阻塞后就会触发120秒的默认超时(这个超时不受你全局设置的时长影响)。

具体修复方案

1. 给catch块加重试次数限制,避免死循环

无限循环读取driver.Url只会持续触发超时,改成有限次数重试,超过次数则重启会话:

catch (Exception e) {
    var newsUrl = "https://www.dunavmost.com/novini/";
    int maxRetries = 3;
    int retryCount = 0;
    
    while (retryCount < maxRetries) {
        try {
            string currentUrl = driver.Url; // 单独捕获读取URL的异常
            if (currentUrl.Contains(newsUrl)) {
                driver.Navigate().Back();
                Console.WriteLine("Went back because the URL contains newsUrl");
                // 回退后给浏览器留恢复时间
                Thread.Sleep(new Random().Next(2000, 5000));
            } else {
                Console.WriteLine("BREAK!");
                break;
            }
        } catch (WebDriverTimeoutException urlEx) {
            retryCount++;
            Console.WriteLine($"读取URL超时,重试第{retryCount}次");
            // 尝试刷新页面恢复会话
            try {
                driver.Navigate().Refresh();
                Thread.Sleep(3000);
            } catch {
                // 刷新失败直接跳出,避免卡死
                break;
            }
        }
    }
    // 重试耗尽则重启WebDriver
    if (retryCount >= maxRetries) {
        Console.WriteLine("会话异常,重启WebDriver");
        driver.Quit();
        // 重新初始化driver
        driver = new ChromeDriver();
        // 恢复超时设置
        driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(60);
        driver.Manage().Timeouts().CommandTimeout = TimeSpan.FromSeconds(600);
    }
}

2. 优化主逻辑的页面切换方式,减少回退操作

多次Navigate().Back()容易导致浏览器历史栈混乱,改用新标签页处理新闻:

// 主逻辑中处理新闻链接的部分
string mainWindow = driver.CurrentWindowHandle;
IWebElement newsLink = driver.FindElement(By.CssSelector("xxx"));
// 用JS打开新标签页
((IJavaScriptExecutor)driver).ExecuteScript("window.open(arguments[0]);", newsLink.GetAttribute("href"));
// 切换到新标签页
driver.SwitchTo().Window(driver.WindowHandles.Last());

try {
    string currentUrl = driver.Url;
    if (currentUrl.Contains("Error404")) {
        driver.Close();
        driver.SwitchTo().Window(mainWindow);
    } else {
        Console.WriteLine(currentUrl);
        Console.WriteLine("In try-catch block to create the news");
        CreateTheNews(driver);
        driver.Close();
        driver.SwitchTo().Window(mainWindow);
        Thread.Sleep(new Random().Next(1000, 3000));
        var PaginateDivExists = driver.FindElements(By.CssSelector("div.paginate")).Count > 0;
        // 主页面就是列表页,分页逻辑可简化
    }
} catch (Exception e) {
    // 异常时直接关闭标签页切回主页面
    try { driver.Close(); } catch {}
    driver.SwitchTo().Window(mainWindow);
    // 后续重试逻辑
}

3. 确保WebDriver与浏览器版本兼容

版本不匹配是WebDriver会话异常的常见原因,需保证ChromeDriver与Chrome浏览器的主版本号一致。

4. 明确设置各类超时参数

避免超时参数遗漏,覆盖所有场景:

var timeouts = driver.Manage().Timeouts();
timeouts.PageLoad = TimeSpan.FromSeconds(60); // 页面加载超时
timeouts.ImplicitWait = TimeSpan.FromSeconds(10); // 元素隐式等待
timeouts.AsynchronousJavaScript = TimeSpan.FromSeconds(30); // JS执行超时
// 若是RemoteWebDriver,单独设置CommandTimeout
if (driver is RemoteWebDriver remoteDriver) {
    remoteDriver.CommandTimeout = TimeSpan.FromSeconds(600);
}

额外建议

  • 每爬取20页左右重启一次WebDriver,避免内存泄漏或会话异常累积
  • 加入详细日志,记录爬取页面、异常信息,方便定位具体问题点
  • 优先使用显式等待(WebDriverWait)而非隐式等待,避免等待逻辑冲突

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 17:42:44