C# 无法使用HtmlAlityPack C中的X-Path获取html元素

C# 无法使用HtmlAlityPack C中的X-Path获取html元素,c#,.net,html-agility-pack,C#,.net,Html Agility Pack,我试图通过使用x-path树元素来获取元素,但显示为空,而这种类型的x-path对我来说适用于其他站点,只有2%的站点这种类型的x-path不起作用,我也尝试了chrome的x-path,但当我的x-path不起作用时,chrome x-path也不起作用 public static void Main() { string url = "http://www.ndrf.gov.in/tender"; HtmlWeb web = new HtmlWeb()

我试图通过使用x-path树元素来获取元素,但显示为空,而这种类型的x-path对我来说适用于其他站点,只有2%的站点这种类型的x-path不起作用,我也尝试了chrome的x-path,但当我的x-path不起作用时,chrome x-path也不起作用

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
    }

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


使用Fizzler.Systems.HtmlAgilityPack 详情如下:
此库添加了名为QuerySelector和QuerySelectorAll的扩展方法,它们采用CSS选择器而不是XPath。

@QHarr建议的答案非常有效,但使用正确的x路径得到null的原因是,在表周围添加了一个包装器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>

Ali Bordbar非常完美,当我在WebBrowser控件中导航Url时,这个Url添加了一个包装器div,所有JavaScript文件都已加载, 但当我使用HtmlWeb加载URL时,没有加载任何JavaScript文件。 HtmlWeb检索服务器发送的静态HTML响应,并且不执行任何javascript,而WebBrowser会执行。 因此WebBrowser控制HTMLDOM数据XPath和HtmlWeb HTMLDOM数据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;
        }
    }
} 

不清楚你在追求什么。你打算写下整张表还是一行?还是别的什么?我也建议使用anglesharp而不是agility pack。Agility pack似乎不再维护。QHarr感谢回复…我想要整个表QHarr感谢回复..如果有多个表,你应该怎么做..重要的是在我的项目中,我给用户在鼠标上选择元素,在WebBrowser控件上悬停,当他选择元素时,我的代码生成X路径。当网站由用户在WebBrowser控件中加载,该控件具有任何标记,如table、div span等。当用户通过鼠标单击进行选择时,不存在fix//table元素或任何其他元素。没有神奇的方法,当然也不使用xpath。例如,有一些方法可以动态遍历,直到找到某个值为止。如果有多个表,则选择多个节点并循环是一种方式。听起来您希望得到的答案与在浏览器中单击鼠标右键复制xpath相同,这超出了本网站的范围。Ali Bordbar感谢您的回答。你的X路径树工作得很好。但在我的项目中将有多个网站在那个时候,我如何才能确定是否有任何包装div有或没有。因为我正在生成完美的HTMLX-Path树。好吧,确保类似情况不会发生的一种方法是在不使用javascript的情况下浏览目标网页。禁用javascript(如中所述)并刷新页面,然后使用x路径查找正确的元素
<div class="view-content">
    <!-- Your table is here -->
</div>
var nodetest1 = htmlDoc.DocumentNode.SelectSingleNode("/html[1]/body[1]/section[2]/div[1]/div[1]/div[1]/div[1]/table[1]");
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;
        }
    }
}