HtmlAgilityPack 可见区域有多深?

How deep is the visible area of HtmlAgilityPack?

我需要从博客中获取一些 post。一切顺利,直到我想获得 post 创建日期。 DOM-树是:

div class="stories-feed__container" 
  -> article 
     -> div class="story__main" 
       -> div class="story__footer" 
         -> div class="story__user user" 
           -> div class="user__info-item" 
             -> time datetime="date and time in UTC format".

所以我写了代码:

    HtmlWeb web = new HtmlWeb();
    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
    doc = web.Load("https://pikabu.ru/@serhiy1994");
    string postDate = doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'stories-feed__container')]/article[2]/div[contains(@class, 'story__main')]/div[contains(@class, 'story__footer')]/div[contains(@class, 'story__user user')]/div[contains(@class, 'user__info-item')]/time").GetAttributeValue("datetime", "NULL"); // e.g. for the 2nd article on the page

它 return 是 NullReferenceException。 但是,如果您停在 "div class="story__user 用户"" 级别(例如,

    string postDate = doc.DocumentNode.SelectSingleNode("//div[contains(@class, 'stories-feed__container')]/article[2]/div[contains(@class, 'story__main')]/div[contains(@class, 'story__footer')]/div[contains(@class, 'story__user user')]").InnerHtml;

它工作正常,return 你是内部 HTML 代码。 所以我认为 HtmlAgilityPack 有类似“最大可见性级别”的东西,你将无法使用更深的 markdown 进行操作。

我是对的还是我编码有误?

原页面代码在这里:https://pastebin.com/jFC0XD9C

HtmlAgility 将抓取整个网站,无论您想抓取多深。您可以使用它来找到您要查找的项目,因为您 不必 必须提供完整路径。

这将搜索整个站点并查找具有 class 名称 user__info-item 的第一个 <div> 标签。如果有多个标签,您还可以将 SelectSingleNode 更改为 SelectNodes,然后循环遍历它们以获取日期。

    HtmlWeb web = new HtmlWeb();
    HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
    doc = web.Load("https://pikabu.ru/@serhiy1994");
    var postDate = doc.DocumentNode.SelectSingleNode("//div[@class='user__info-item']/time");
    Console.WriteLine(postDate.InnerText);

你的代码有什么问题?

您上面的代码不起作用的原因是您缺少另一个 div,“<div class="user__info user__info_left">”。

如果您这样编写代码,它就可以工作。

    var nodes = doc.DocumentNode.SelectSingleNode("//div[@class='story__main']/div[@class='story__footer']/div[@class='story__user user']/div[@class='user__info user__info_left']/div[@class='user__info-item']/time");
    Console.WriteLine(nodes.InnerText);

另一种方式

另一种方法是搜索父项 div。找到父标签后,在该标签下搜索以找到您要查找的内容。

    var nodes = doc.DocumentNode.SelectNodes("//div[@class='story__user user']");
    foreach (HtmlNode node in nodes)
    {
        // Search within each node using .// notation
        var timeNodes = node.SelectSingleNode(".//div[@class='user__info-item']/time");
        Console.WriteLine(timeNodes.InnerText);
    }

Tested Code here