如何仅用HtmlAgilityPack提取指定class下的特定文本?
问题描述
现有如下HTML结构:
... <ul class="not-this-class" ...> ... <!-- some "<li> <a href.. > </a> </li>" here --> </ul> <ul class="yes-this-class" ...> <li> <a href="/some-text-1">some text 1</a> </li> <li> <a href="/some-text-2">some text 2</a> </li> <li> <a href="/some-text-3">some text 3</a> </li> ... </ul> <ul class="not-this-class-either" ...> ... <!-- some "<li> <a href.. > </a> </li>" here --> </ul>
已能通过以下代码选中class为yes-this-class的节点:
HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument(); document.LoadHtml(responseString.ToString()); HtmlNode htmlNode = document.DocumentNode.SelectSingleNode("//*[@class='yes-this-class']");
需要仅用HtmlAgilityPack提取出如下结构的文本(无需正则表达式):
<ul> <li>some text 1</li> <li>some text 2</li> <li>some text 3</li> </ul>
此前尝试的代码无效:
HtmlNodeCollection htmlNodes = document.DocumentNode.SelectNodes("//*[@class='yes-this-class']/[@a='href']");
正确实现方法
你之前的XPath语法错误,/[@a='href']不是合法的路径表达式。以下是两种可行的实现方式:
方式一:通过XPath直接获取所有目标<a>节点,再构建结果
HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument(); document.LoadHtml(responseString.ToString()); // 选中目标ul下的所有a节点 HtmlNodeCollection linkNodes = document.DocumentNode.SelectNodes("//ul[@class='yes-this-class']/li/a"); // 创建新的ul节点用于组装结果 HtmlNode resultUl = document.CreateElement("ul"); foreach (HtmlNode linkNode in linkNodes) { // 创建li节点,将a的文本内容赋值给li HtmlNode li = document.CreateElement("li"); li.InnerText = linkNode.InnerText.Trim(); resultUl.AppendChild(li); } // 获取最终的HTML字符串 string finalHtml = resultUl.OuterHtml;
方式二:先获取目标ul,再遍历其下的li节点
HtmlAgilityPack.HtmlDocument document = new HtmlAgilityPack.HtmlDocument(); document.LoadHtml(responseString.ToString()); HtmlNode targetUl = document.DocumentNode.SelectSingleNode("//ul[@class='yes-this-class']"); // 创建新的ul节点 HtmlNode resultUl = document.CreateElement("ul"); // 遍历目标ul下的所有li节点 foreach (HtmlNode li in targetUl.SelectNodes(".//li")) { // 获取li下a的文本 string text = li.SelectSingleNode(".//a").InnerText.Trim(); HtmlNode newLi = document.CreateElement("li"); newLi.InnerText = text; resultUl.AppendChild(newLi); } string finalHtml = resultUl.OuterHtml;
注意事项:
- XPath路径要精准:
//ul[@class='yes-this-class']/li/a表示选中所有class为yes-this-class的ul下直接子li中的a节点 - 若ul的class包含多个值(比如
class="yes-this-class other-class"),精确匹配可能失效,可改用contains(@class, 'yes-this-class'),但需注意避免匹配到相似名称的class - 通过创建新节点组装结果,能避免原节点的冗余属性或内容混入最终输出
内容的提问来源于stack exchange,提问作者ssd
相关产品推荐
相关产品推荐

