2011-12-13 10 views
9

¿Cómo voy a analizar con eficacia el valor del atributo href de esto:HTML agilidad paquete: análisis de una etiqueta 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> 
[...] 

estoy interesado en que el jugador id, que es: Aquí está el código que han hasta ahora:

 // 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; 
        } 
       } 
+0

Si ha codificado índices en el 'switch', ¿para qué usar el' for' ¿lazo? ¿Por qué no 'player.Position = cols [2] .InnerText;' –

+0

Buen punto. Estoy reciclando un código viejo que escribí, así que no he pensado en eso. –

Respuesta

20

Basado en su ejemplo, esto funcionó para mí:

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]); 

Para su uso real, es necesario agregar la comprobación de errores, etc.

+0

¡También funciona para mí! ¿Es solo yo o esto es bastante inconveniente porque tenemos que usar 'htmlDoc' en el que encontramos todos los nodos con la clase 'undMe', mientras que en su lugar podríamos usar' cols [j] 'que tienen' href' en su InnerHtml? –

+0

Hace una suposición muy fuerte sobre dónde se encuentra su enlace; esto podría funcionar bien, pero es muy rígido y se romperá, es decir, si agrega otra columna. El enfoque presentado no lo haría desde su * consulta * para el enlace sobre supuestos mínimos – BrokenGlass

+0

En realidad, el único problema con esto es el 'Primer()' que es estático y siempre trae el primer elemento que encuentra. Necesito algo dinámico que pueda obtener el elemento real. –

2

utilizar una expresión XPath para encontrarlo:

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); 
} 
Cuestiones relacionadas