You need to enable JavaScript to run this app. 网页爬取中如何用if替代try/catch规避ArgumentNullException
优惠活动
大模型
产品
解决方案
定价
更多

网页爬取中如何用if替代try/catch规避ArgumentNullException

异常根因

你的链式调用里有三处未判空的风险点,任意一处触发就会抛出空异常:

  • document.DocumentNode.SelectNodes("//td") 当页面无任何<td>节点时,HtmlAgilityPack的该方法返回null而非空集合,直接对null调用Where()会触发空引用类错误
  • 遍历td节点时,x.Attributes["title"] 遇到无title属性的td节点时返回null,直接访问.Value会触发错误
  • 即使title属性存在,其Value可能为null字符串,直接调用.Contains("Log.html")会抛出ArgumentNullException
正确实现逻辑

不要直接写嵌套链式判空,把每一层可能为null的节点都做判空兜底,同时避免重复调用SelectNodes浪费性能:

// 第一步:先获取所有td节点,空结果直接兜底为空集合,避免null引用
var allTdNodes = document.DocumentNode.SelectNodes("//td") ?? Enumerable.Empty<HtmlNode>();

// 第二步:带全量判空的筛选逻辑,符合条件的节点直接存下来,无需重复查询
var matchedNodes = allTdNodes
    // 先筛选存在title属性的节点
    .Where(td => td.Attributes["title"] != null)
    // 再筛选title值非空、且包含目标字符串的节点
    .Where(td => !string.IsNullOrEmpty(td.Attributes["title"].Value) 
                 && td.Attributes["title"].Value.Contains("Log.html"))
    .ToArray();

// 第三步:直接对筛选后的结果做业务判断
if (matchedNodes.Any())
{
    // 复用之前筛选好的节点,不用重复执行DOM查询
    var nodes = matchedNodes;
    if (nodes.Length > 1)
    {
        nodes = nodes.Where((source, index) => index != 1).ToArray();
    }
    // [后续原有业务逻辑]
}
else
{
    LogException("Item is null", taskId, buildId);
}
额外注意点
  • 无需写xxx is true这种冗余判断,Any()本身返回布尔值,直接写在if条件里即可
  • 优先复用第一次查询到的节点集合,避免重复爬取DOM带来的性能损耗,也能避免两次查询结果不一致的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.30 12:15:09