在 XPath 中对结果进行分组

Grouping Results in XPath

简介:

假设我们有这样的 HTML 代码:

<div class="search-result">            
    <h2>TV-Series</h2>
        <ul>

             <li>
     <div class="title">
         <a href="/subtitles/prison-break-sequel-first-season">Prison Break : Sequel - First Season</a>             
     </div>        
     <span class="subtle count">10 subtitles</span>
             </li>

             <li>            
     <div class="title">
         <a href="/subtitles/prison-break-fourth-season">Prison Break - Fourth Season</a>            
     </div>        
     <span class="subtle count">1232 subtitles</span>
             </li>

         </ul>

    <h2>Popular</h2>
        <ul>

             <li>
     <div class="title">
         <a href="/subtitles/prison-break-fourth-season">Prison Break - Fourth Season (2008)</a>
     </div>
     <div class="subtle count">
        1232 subtitles
     </div>

             </li>

             <li>
     <div class="title">
         <a href="/subtitles/prison-break-third-season">Prison Break - Third Season (2007)</a>
     </div>
     <div class="subtle count">
        644 subtitles
    </div>
             </li>

        </ul>   

</div>

页面是这样的:

您可以在此处查看原始站点:SubScene

我正在编写一个 C# 桌面应用程序,用于获取此站点的信息。

在学习 HTML Agility Pack 之前,我使用正则表达式。

使用此模式:<h2>[\s\S]+?</ul> 我将系列(如电视剧、流行和...)分开。

然后在 Rgular Expression 上使用此模式:<li>[\s\S]+?<a href="(.+)">(.+)</a>[\s\S]+?class="subtle count"[\s\S]+?(\d*)[\s\S]+?</li> 我从该站点获得分类信息。

with MatchCollection & using Groups (that difined with Parenthesis),我在 Regex 中的方法,返回了每个系列的二维列表,每一行都是关于一部电影的,列包括:电影名称,字幕数量和字幕下载 Link .

那个二维列表变成了像这样的数据库之类的东西:

现在我学会了HTML敏捷包

问题:

1- 如何使用 XPath 在 HTML Agility Pack 中创建这样一个列表?

2- 我可以使用哪个 XPath 创建像您之前看到的 Regex 这样的组?

非常感谢。

Martin Honnen 的评论是正确的,通过 XPath 'grouping' 提供的功能并不多。但是,可以使用循环和 运行 一组元素上的一组 XPath 来提取您想要的数据。

首先,您提取每个标题元素,然后从标题中提取每个列表项,然后运行一个文件 XPath 从每个元素中提取您想要的值。

注意:此代码是使用针对 XDocument 的 XPath 而不是 HTML Agility Pack 编写的,但无论如何 XPath 都应该相同。

var titleNodes = d.XPathSelectElements("/div[@class='search-result']/h2");
foreach (var titleNode in titleNodes)
{
    string title = titleNode.Value.Dump();
    var listItems = titleNode.XPathSelectElements("following-sibling::ul[1]/li");

    foreach (var listItem in listItems)
    {
        var itemData = listItem.XPathEvaluate("div[@class='title']/a/text() | *[@class='subtle count']/text()");
    }
}

请注意,在最后一个表达式中使用了 XPath | 运算符,以便在单个 XPath 调用中 select 多个不同 children 的值。这些值有点像您想要的 'grouped'。