HTML 敏捷包:解析 href 标签

Posted

技术标签:

【中文标题】HTML 敏捷包:解析 href 标签【英文标题】:HTML Agility pack: parsing an href tag 【发布时间】:2012-01-19 19:49:00 【问题描述】:

我将如何有效地从中解析 href 属性值:

<tr>
<td rowspan="1" colspan="1">7</td>
<td rowspan="1" colspan="1">
<a class="undMe" href="/ice/player.htm?id=8475179" rel="skaterLinkData" shape="rect">D. Kulikov</a>
</td>
<td rowspan="1" colspan="1">D</td>
<td rowspan="1" colspan="1">0</td>
<td rowspan="1" colspan="1">0</td>
<td rowspan="1" colspan="1">0</td>
[...]

我有兴趣拥有玩家 ID,即:8475179这是我目前拥有的代码:

        // Iterate all rows (players)
        for (int i = 1; i < rows.Count; ++i)
        
            htmlNodeCollection cols = rows[i].SelectNodes(".//td");

            // new player
            Dim_Player player = new Dim_Player();

                // Iterate all columns in this row
                for (int j = 1; j < 6; ++j)
                
                    switch (j) 
                        case 1: player.Name = cols[j].InnerText;
                                player.Player_id = Int32.Parse(/* this is where I want to parse the href value */); 
                                break;
                        case 2: player.Position = cols[j].InnerText; break;
                        case 3: stats.Goals = Int32.Parse(cols[j].InnerText); break;
                        case 4: stats.Assists = Int32.Parse(cols[j].InnerText); break;
                        case 5: stats.Points = Int32.Parse(cols[j].InnerText); break;
                    
                

【问题讨论】:

如果switch 中有硬编码索引,为什么要使用for 循环?为什么不player.Position = cols[2].InnerText; 好点。我正在回收我写的一些旧代码,所以我没有想到。 【参考方案1】:

使用 XPath 表达式查找它:

 foreach (HtmlNode link in doc.DocumentNode.SelectNodes("//a[@class='undMe']"))
 
      HtmlAttribute att = link.Attributes["href"];
      Console.WriteLine(new Regex(@"(?<=[\?&]id=)\d+(?=\&|\#|$)").Match(att.Value).Value);
 

【讨论】:

【参考方案2】:

根据您的示例,这对我有用:

HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.Load("test.html");
var link = htmlDoc.DocumentNode
                  .Descendants("a")
                  .First(x => x.Attributes["class"] != null 
                           && x.Attributes["class"].Value == "undMe");

string hrefValue = link.Attributes["href"].Value;
long playerId = Convert.ToInt64(hrefValue.Split('=')[1]);

实际使用需要添加错误检查等

【讨论】:

对我也有用!只是我还是这很不方便,因为我们必须使用htmlDoc,在其中我们可以找到所有具有“undMe”类的节点,而我们可以使用cols[j],它的InnerHtml 中有href 您对链接的位置做出了非常强烈的假设 - 这可能工作正常,但非常僵化并且会中断,即如果您添加另一列。所提出的方法不会因为它在最小假设下查询链接 实际上,唯一的问题是First(),它是静态的,总是带来他找到的第一个元素。我需要一些动态的东西来获取实际元素。 啊……找到了:var link = cols.Descendants("a").First();,因为我只想在我已经找到的列中搜索。 这是一个很棒的答案......它工作得很好。唯一的问题是将 .First 替换为 .FirstOrDefault ,否则会抛出异常。

以上是关于HTML 敏捷包:解析 href 标签的主要内容,如果未能解决你的问题,请参考以下文章

使用php simple html dom parser解析html标签

使用 html 敏捷包抓取表数据

Spring源码解析-默认标签解析-2

thinkphp禁止模版标签解析

利用a标签自动解析URL

HTML 敏捷包 - 解析表