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

C# Try-catch无法捕获预期的NoSuchElementException问题

Selenium C#爬虫NoSuchElementException捕获失败问题解决

问题描述

我用C#开发了基于Selenium的新闻爬取程序,多数新闻页面顶部包含图片,部分新闻会用视频替代图片,这种场景下需要为其设置默认图片。原代码通过driver.FindElement(By.CssSelector("tbody > tr > td > img"))查找图片元素,不存在时会抛出NoSuchElementException,原本用try-catch块捕获该异常并设置默认图片,但近期未修改代码的情况下,该异常突然无法被捕获,直接变为未处理异常。先后尝试捕获通用Exception、添加专门的NoSuchElementException分支,问题均未解决。

相关代码片段

try {
  var imageElement = driver.FindElement(By.CssSelector("tbody > tr  > td > img"));
  imageSrc = imageElement.GetAttribute("src");
} catch (NoSuchElementException e) {
  Console.WriteLine($"Exception when looking for imageElement! {e.Message}");
  imageSrc = "https://digitalfinger.id/wp-content/uploads/2019/12/no-image-available-icon-6.png";
} catch (Exception e) {
  Console.WriteLine($"Exception when looking for imageElement! {e.Message}");
  imageSrc = "https://digitalfinger.id/wp-content/uploads/2019/12/no-image-available-icon-6.png";
}

完整方法代码

private News GetTheNewsData(ChromeDriver driver, WebDriverWait wait) {
  Console.OutputEncoding = Encoding.UTF8;

  string imageSrc = "";
  string date = "";
  DateTime dateParsed = DateTime.Now;

  try {
    var imageElement = driver.FindElement(By.CssSelector("tbody > tr  > td > img"));
    imageSrc = imageElement.GetAttribute("src");
  } catch (NoSuchElementException e) {
    Console.WriteLine($"Exception when looking for imageElement! {e.Message}");
    imageSrc = "https://digitalfinger.id/wp-content/uploads/2019/12/no-image-available-icon-6.png";
  } catch (Exception e) {
    Console.WriteLine($"Exception when looking for imageElement! {e.Message}");
    imageSrc = "https://digitalfinger.id/wp-content/uploads/2019/12/no-image-available-icon-6.png";
  }

  try {
    //Wait for the title element to load
    wait.Until(ExpectedConditions.ElementExists(By.CssSelector("h1.title")));
    //Get the title element
    var titleElement = driver.FindElement(By.CssSelector("h1.title"));
    var title = titleElement.Text;

    //Wait for the date element to load
    wait.Until(ExpectedConditions.ElementExists(By.CssSelector("div.art_author")));
    //Get the date element
    var dateElement = driver.FindElement(By.CssSelector("div.art_author"));

    if (dateElement.Text.StartsWith("Обновена")) {
      var pipeIndex = dateElement.Text.IndexOf('|');
      date = dateElement.Text.Substring("Обновена: ".Length, pipeIndex - "Обновена: ".Length).Trim();
      Console.WriteLine($"Trimmed date: {date}");
    } else {
      date = dateElement.Text.Split(',')[0];
    }

    try {
      dateParsed = DateTime.ParseExact(date, "d MMM yyyy HH:mm", new CultureInfo("bg-BG"), DateTimeStyles.None);
    } catch (Exception e) {
      Console.WriteLine($"Exception parsing the date! {e.Message}");
      dateParsed = new DateTime(1000, 1, 1, 12, 30, 0);
    }
    Console.WriteLine(dateParsed.ToString("dd/MM/yyyy HH:mm"));

    //Wait for the div with content paragraphs to load
    wait.Until(ExpectedConditions.ElementExists(By.CssSelector("div#art_start")));
    //Get the div with content paragraphs
    var divWithContentParagraphs = driver.FindElement(By.CssSelector("div#art_start"));
    //Get the content paragraphs
    var contentParagraphs = divWithContentParagraphs.FindElements(By.CssSelector("p"));

    var sterilizedParagraphs = SterilizeTheNews(contentParagraphs);

    var currentNews = new News {
      Title = title,
        Content = sterilizedParagraphs,
        Date = dateParsed,
        ImageUrl = imageSrc
    };

    return currentNews;
  } catch (Exception e) {
    Console.WriteLine($"Exception in getting the news data! {e.Message}");

    return null;
  }
}

可能原因及解决方案

1. 命名空间冲突

如果项目中引用了多个包含NoSuchElementException的命名空间,可能导致捕获的异常并非Selenium抛出的实例。

解决办法:捕获异常时指定完整命名空间:

catch (OpenQA.Selenium.NoSuchElementException e)
{
    Console.WriteLine($"查找图片元素出错:{e.Message}");
    imageSrc = "默认图片URL";
}

2. 改用FindElements避免异常

FindElement找不到元素时会抛出异常,而FindElements会返回空集合,无需依赖异常捕获,代码更稳定。

解决办法:

var imageElements = driver.FindElements(By.CssSelector("tbody > tr > td > img"));
if (imageElements.Any())
{
    imageSrc = imageElements.First().GetAttribute("src");
}
else
{
    Console.WriteLine("未找到图片元素,使用默认图片");
    imageSrc = "默认图片URL";
}

3. 排查实际异常类型

捕获通用异常时输出完整堆栈信息,确认实际抛出的异常类型及来源:

catch (Exception e)
{
    Console.WriteLine($"查找图片元素出错:{e.Message}\n堆栈信息:{e.StackTrace}");
    imageSrc = "默认图片URL";
}

4. 添加元素等待逻辑

若图片是异步加载,直接执行FindElement可能因元素未加载完成抛出异常,可添加等待逻辑确保元素加载:

try
{
    wait.Until(ExpectedConditions.ElementIsVisible(By.CssSelector("tbody > tr > td > img")));
    var imageElement = driver.FindElement(By.CssSelector("tbody > tr > td > img"));
    imageSrc = imageElement.GetAttribute("src");
}
catch (OpenQA.Selenium.TimeoutException)
{
    Console.WriteLine("图片元素加载超时,使用默认图片");
    imageSrc = "默认图片URL";
}
catch (OpenQA.Selenium.NoSuchElementException e)
{
    Console.WriteLine($"查找图片元素出错:{e.Message}");
    imageSrc = "默认图片URL";
}

内容的提问来源于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 04:03:08