【问题标题】:C# htmlagilitypack node.xpathC# htmlagilitypack node.xpath
【发布时间】:2016-06-18 02:01:32
【问题描述】:

我正在使用 htmlagilitypack 在 C# 中制作一个 webscraper 应用程序,现在我想要一个下拉菜单来选择文档中的一个元素。我想查看 xpath 的字符串,这是我希望的结果

//a[@href='http://www.google.com']

但我得到的 xpath 是

/html[1]/body[1]/div[1]/a[1]

有什么方法可以让 xpath 更易读吗? 我使用的代码是:

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(data);
List<string> nodes = new List<string>();
foreach (HtmlNode n in doc.DocumentNode.Descendants()){
        nodes.Add(n.XPath);
}
List<string> ComboItems = nodes.Distinct().ToList();
_comboFilterNode.ItemsSource = ComboItems;

它不必是我给出的第一个示例的格式,但我确实需要一些东西,因此您无需阅读整个 HTML 文件即可知道它是什么元素。

或获取方式:

<a href="http://www.google.com/"/>

它并不总是&lt;a&gt;,我不想要innerHTML

提前感谢您的帮助:D

【问题讨论】:

  • "...我不想要 innerHTML",innerHTML 有什么问题? (我会采用这种方式,而不是尝试获取给定元素的不同 XPath,这样构建起来会更加复杂)
  • 如果我得到了 innerHTML,我也得到了所有的子元素,我不想要那个

标签: c# html xpath html-agility-pack


【解决方案1】:

您可以结合使用HtmlNode 名称和属性集合来构建给定HtmlNode 的HTML 标记,不包括其内容。

例如,假设您有变量foo 引用的HtmlNode 实例,您可以执行以下操作:

HtmlNode foo;

var attributes = string.Join(" ", 
                             foo.Attributes
                                .Select(o => String.Format("{0}=\"{1}\"", o.Name, o.Value))
                            );

//combine element name and the attributes collection to create a representative HTML markup
var result = String.Format("<{0} {1}/>", foo.Name, attributes);

完整的工作演示示例:

var html = @"<a href='http://www.google.com/'>
    <span>foobar</span>
    <span>foobaz</span>
</a>";
var doc = new HtmlDocument();
doc.LoadHtml(html);
var foo = doc.DocumentNode.FirstChild;
var attributes = string.Join(" ", 
                         foo.Attributes
                            .Select(o => String.Format("{0}=\"{1}\"", o.Name, o.Value))
                        );
var result = String.Format("<{0} {1}/>", foo.Name, attributes);
Console.WriteLine(result);

dotnetfiddle demo

输出:

<a href="http://www.google.com/"/>

【讨论】:

    【解决方案2】:

    我现在有:

    foreach (HtmlNode n in doc.DocumentNode.Descendants())
    {
            if (n.Attributes.Count != 0)
            {
                  nodes.Add("//"+n.Name + "[@" + n.Attributes[0].Name+"='"+n.Attributes[0].Value+"']");
             }
             else
             {
                   nodes.Add(n.Name);
              }
      }
    
      List<string> ComboItems = nodes.Distinct().ToList();
      _comboFilterNode.ItemsSource = ComboItems;
    

    遗憾的是,我现在只有一个属性可以过滤它,但它可以满足它需要做的事情,并且它会在 XPath 中返回。

    【讨论】:

      猜你喜欢
      • 2012-12-10
      • 2020-09-04
      • 1970-01-01
      • 2022-08-23
      • 2016-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-08
      相关资源
      最近更新 更多