无法通过在 HtmlAgilityPack C# 中使用 X-Path 获取 html 元素



我正在尝试使用 x 路径树元素获取元素,但显示 null,这种类型的 x 路径对我来说适用于其他站点,只有 2% 的网站这种类型的 X-Path 不起作用,我也尝试了来自 chrome 的 x 路径,但是当我的 x 路径不起作用时,铬 x 路径也不起作用。

public static void Main()
{
string url = "http://www.ndrf.gov.in/tender";
HtmlWeb web = new HtmlWeb();
var htmlDoc = web.Load(url);
var nodetest1 = htmlDoc.DocumentNode.SelectSingleNode("/html[1]/body[1]/section[2]/div[1]/div[1]/div[1]/div[1]/div[2]/table[1]"); // i want this type // not wroking
//var nodetest2 = htmlDoc.DocumentNode.SelectSingleNode("//*[@id="content"]/div/div[1]/div[2]/table"); // from Google chrome // not wroking
//var nodetest3 = htmlDoc.DocumentNode.SelectSingleNode("//*[@id="content"]"); // by ID but i don't want this type  // wroking
Console.WriteLine(nodetest1.InnerText); //fail
//Console.WriteLine(nodetest2.InnerText); //fail
//Console.WriteLine(nodetest3.InnerText); //proper but I don't want this type
}

@QHarr建议的答案非常有效,但是您获得 null 的正确 x 路径的原因是站点标头中有一个 javascript 文件,该文件在表周围添加了一个包装器div,并且由于在 HtmlAgilityPack 中获取结果似乎没有加载或执行 js,因此 x 路径返回 null。

在 js 运行之后,您观察到的是:

<div class="view-content">
<div class="guide-text">
...
</div>
<div class="scroll-table1">
<!-- Your table is here -->
</div>
</div>

但实际上你得到的是 js,是:

<div class="view-content">
<!-- Your table is here -->
</div>

因此,您的 X 路径应该是:

var nodetest1 = htmlDoc.DocumentNode.SelectSingleNode("/html[1]/body[1]/section[2]/div[1]/div[1]/div[1]/div[1]/table[1]");

在浏览器中使用时,您的 xpath 会选择整个表。您可以按如下方式缩短和使用(小提琴(:

using System;
using HtmlAgilityPack;
public class Program
{
public static void Main()
{
string url = "http://www.ndrf.gov.in/tender";
HtmlWeb web = new HtmlWeb();
var htmlDoc = web.Load(url);
var nodetest1 = htmlDoc.DocumentNode.SelectSingleNode("//table");  
Console.WriteLine(nodetest1.InnerText); 
}
}

use Fizzler.Systems.HtmlAgilityPack 详情请见此处 : https://www.nuget.org/packages/Fizzler.Systems.HtmlAgilityPack/此库添加了名为 QuerySelector 和 QuerySelectorAll 的扩展方法,这些方法采用 CSS Selector 而不是 XPath。

Ali Bordbar 捕捉完美, 当我在这个所有 JavaScript 文件中的 Web 浏览器控件中导航 URL 时,此 URL 添加了一个包装器div, 但是当我使用 HtmlWeb 加载 URL 时,没有加载任何 JavaScript 文件。 HtmlWeb检索服务器发送的静态HTML响应,并且不执行任何javascript,而WebBrowser会。 所以 WebBrowser 控制 HTML DOM 数据 XPath 和 HtmlWeb HTML DOM 数据 XPath 不匹配。

我下面的代码非常适合这种切换

HtmlWeb web = new HtmlWeb();
web.AutoDetectEncoding = true;
HtmlAgilityPack.HtmlDocument theDoc1 = web.Load("http://www.ndrf.gov.in/tender");
var HtmlDoc = new HtmlAgilityPack.HtmlDocument();
var bodytag = theDoc1.DocumentNode.SelectSingleNode("//html");
HtmlDoc.LoadHtml(bodytag.OuterHtml);
var xpathHtmldata = HtmlDoc.DocumentNode.SelectSingleNode(savexpath); //savexpath is my first xpath make from HTML DOM data of WebBrowser control which is work for most url.
if (xpathHtmldata == null)
{
//take last tag name from first xpath
string mainele = savexpath.Substring(savexpath.LastIndexOf("/") + 1);
if (mainele.Contains("[")) { mainele = mainele.Remove(mainele.IndexOf("[")); }
//collect all tag name with name of which is sotre in mainele variable
var taglist = HtmlDoc.DocumentNode.SelectNodes("//" + mainele);
foreach (var ele in taglist) //check one by one element 
{
string htmltext1 = ele.InnerText;
htmltext1 = Regex.Replace(htmltext1, @"s", "");
htmltext1 = htmltext1.Replace("&amp;", "&").Trim();
htmltext1 = htmltext1.Replace("&nbsp;", "").Trim();
string htmltext2 = saveInnerText; // my previus xpath text from HTML DOM data of WebBrowser control
htmltext2 = Regex.Replace(htmltext2, @"s", "");
if (htmltext1 == htmltext2) // check equality to my previus xpath text..if it is equal thats my new xpath
{
savexpath = ele.XPath;
break;
}
}
} 

最新更新