使用C# HtmlAgilityPack解析网页触发NullReferenceException,求排查问题
问题分析:NullReferenceException异常原因
代码示例
public static (HtmlNodeCollection title, HtmlNodeCollection price) ParsingNodesTP() { HtmlWeb web = new HtmlWeb(); HtmlDocument doc = web.Load("https://rozetka.com.ua/ua/search/?text=Asus+Zenbook+14&producer=asus&page=1"); var titles = doc.DocumentNode.SelectNodes("//a[@class='goods-tile__heading ng-star-inserted']//span"); var price = doc.DocumentNode.SelectNodes("//div[@class='goods-tile__prices']//div[@class='goods-tile__price price--red ng-star-inserted']//p//span[@class='goods-tile__price-value']"); return (titles, price); }
异常信息
System.NullReferenceException: 'Object reference not set to an instance of an object.'
这个异常的核心原因是**SelectNodes方法找不到匹配节点时会返回null**,后续如果直接使用返回的titles或price(比如遍历、访问Count属性等),就会触发空引用异常。具体触发场景包括:
页面结构变更
Rozetka页面用Angular渲染,ng-star-inserted是框架动态生成的类名,可能随版本更新消失或变化;部分商品价格展示结构调整(比如无折扣的商品没有红色价格标签),导致XPath完全匹配不到节点,返回null。XPath表达式过于严格
你的XPath嵌套层级过多,且完全匹配完整class名,只要中间某一层节点不存在(比如部分商品价格节点下没有<p>标签),整个SelectNodes就会返回null。网络加载异常(概率较低)
如果网页加载失败,doc.DocumentNode可能为null,调用SelectNodes时也会触发异常,但HtmlWeb.Load通常会直接抛出网络相关异常,而非返回空的DocumentNode。
解决建议
- 优化XPath表达式:用
contains匹配部分class名,规避动态生成类的影响,同时简化层级:var titles = doc.DocumentNode.SelectNodes("//a[contains(@class, 'goods-tile__heading')]//span"); var price = doc.DocumentNode.SelectNodes("//div[contains(@class, 'goods-tile__prices')]//div[contains(@class, 'goods-tile__price') and contains(@class, 'price--red')]//span[@class='goods-tile__price-value']"); - 空值兜底:给
SelectNodes返回值加空值判断,返回空集合而非null,避免后续调用报错:var titles = doc.DocumentNode.SelectNodes("//a[contains(@class, 'goods-tile__heading')]//span") ?? new HtmlNodeCollection(doc.DocumentNode); var price = doc.DocumentNode.SelectNodes("//div[contains(@class, 'goods-tile__prices')]//div[contains(@class, 'goods-tile__price') and contains(@class, 'price--red')]//span[@class='goods-tile__price-value']") ?? new HtmlNodeCollection(doc.DocumentNode); - 增加异常捕获:捕获网页加载时的网络异常,排查加载失败问题:
try { HtmlDocument doc = web.Load("https://rozetka.com.ua/ua/search/?text=Asus+Zenbook+14&producer=asus&page=1"); } catch (WebException ex) { // 记录日志或提示网络异常 throw; }
内容的提问来源于stack exchange,提问作者Олександр Павлюк
相关产品推荐
相关产品推荐

