Analizar HTML interno

c# html-agility-pack html-parsing

Pregunta

Esto es lo que quiero analizar.

<div class="photoBox pB-ms">
<a href="/user_details?userid=ePDZ9HuMGWR7vs3kLfj3Gg">
<img width="100" height="100" alt="Photo of Debbie K." src="http://s3-media2.px.yelpcdn.com/photo/xZab5rpdueTCJJuUiBlauA/ms.jpg">
</a>
</div>

Estoy usando siguiente XPath para encontrarlo

HtmlNodeCollection bodyNode = htmlDoc.DocumentNode.SelectNodes("//div[@class='photoBox pB-ms']");

Esto está bien y regresa, s yo todos los divs, s con clase photobox

Pero cuando quiero usar ahref

HtmlNodeCollection bodyNode = htmlDoc.DocumentNode.SelectNodes("//div[@class='photoBox pB-ms'//a href]");

Tengo error token no válido.

También he intentado utilizar la consulta

   var lowestreview =
  from main in htmlDoc.DocumentNode.SelectNodes("//div[@class='photoBox pB-ms']") 
   from rating in main.SelectNodes("//a href")
  select new { Main=main.Attributes[0].Value,AHref = rating.ToString() };

¿Alguien me dirá cómo escribir XPath o consulta para obtener este AHref?

Respuesta aceptada

Esto funciona (probado):

HtmlNodeCollection bodyNodes = htmlDoc.DocumentNode
                                      .SelectNodes("//div[@class='photoBox pB-ms']/a[@href]");
foreach(var node in bodyNodes)
{
    string href = node.Attributes["href"].Value;
}

El problema es que has mezclado selectores de atributos y elementos. Además, desde su pregunta no está claro si realmente tenía la intención de consultar una colección .

El selector XPath anterior seleccionará todos a elementos que tienen un href atributo que son nodos hijos de un div elemento con una clase de 'photoBox pB-ms' . Luego puede iterar esta colección y obtener el valor del atributo href de cada elemento.

Además, HtmlAgilityPack ahora es compatible con Linq (desde la versión 1.4), por lo que solo se puede obtener un valor de atributo en particular mucho más fácil (imo) de esta manera:

string hrefValue = htmlDoc.DocumentNode
                          .Descendants("div")
                          .Where(x => x.Attributes["class"].Value == "photoBox pB-ms")
                          .Select(x => x.Element("a").Attributes["href"].Value)
                          .FirstOrDefault();

Respuesta popular

En lugar de analizar XML puede usar HTMLAgilePack

HtmlDocument doc = new HtmlDocument();
doc.LoadHtml([HTML Text]);
foreach(HtmlNode link in doc.DocumentElement.SelectNodes("//a[@href"])
{
    HtmlAttribute att = link["href"];
    // att.Value
}


Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow