Problemas con HtmlAgilityPack

c# html-agility-pack

Pregunta

Yo domino HtmlAgilityPack. Estoy tratando de obtener datos de una página precargada. A saber: Hay una página 1.htm. Quiero obtener el valor de la tabla opuesta a la línea "Sistema operativo". (El documento en sí está adjunto). Hago esto:

private void simpleButton1_Click(object sender, EventArgs e)
        {
            // Создаю экземпляр класса
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            // Загружаю файл
            doc.Load(@"D:\(тут путь к файлу)\1.htm");
            // Пытаюсь получить информацию из ноды, но получаю null
            HtmlAgilityPack.HtmlNode bodyNode = doc.DocumentNode.SelectSingleNode("//TD[@CLASS=pt]");
            ...

En general, es necesario extraer una gran cantidad de información del archivo, pero creo que si se obtiene una línea, más adelante por analogía.

La línea requerida era la siguiente:

 private void simpleButton1_Click(object sender, EventArgs e)
        {
            // Создаю экземпляр класса
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            // Загружаю файл
            doc.Load(@"D:\(тут путь к файлу)\1.htm");

            foreach (HtmlAgilityPack.HtmlNode node in doc.DocumentNode.SelectNodes("//body/table[2]/tr[8]/td[4]"))
            {
                string stroka = node.InnerText;
            }

Pero esta opción está "en la frente". Si no cambia la estructura de mi documento. Y cómo es posible con la ayuda de la búsqueda aún no se ha resuelto.

Archivo

Respuesta aceptada

Esto devolverá un diccionario de tablas por nombre. Cada tabla es un diccionario con la primera columna como clave y la segunda para el valor.

var tables = new Dictionary<string, Dictionary<string, string>>();
var doc = new HtmlDocument();
doc.Load(@"D:\(тут путь к файлу)\1.htm", Encoding.GetEncoding(1251), false);
var tableNames = doc.DocumentNode.SelectNodes("//td[@class='pt']/a").Select(a=>a.Attributes["name"].Value);
foreach(string name in tableNames)
{
    var table = doc.DocumentNode.SelectSingleNode("//table[.//a[@name='" + name + "']]/following-sibling::table[1]");
    int columns = table.SelectNodes(".//tr[1]/td").Count();

    string[] keys = table.SelectNodes(".//tr/td["+(columns-1)+"]").Select(n => n.InnerText.Replace("&nbsp;"," ").Trim()).ToArray();
    string[] values = table.SelectNodes(".//tr/td["+columns+"]").Select(n => n.InnerText.Replace("&nbsp;"," ").Trim()).ToArray();
    var body = new Dictionary<string, string>();
    for (int i = 0; i < keys.Count(); i++)
    {
        string key = keys[i];
        if (body.ContainsKey(key))
            body[key] += ", " + values[i];
        else if( key!="" && values[i]!="")
            body[key] = values[i];

    }
    tables.Add(name, body);

}

Por ejemplo, las tables["power management"] devuelven 4 entradas:

  • [0] {[Ð ¢ ÐµÐºÑƒÑ Ð¸Ð¹ÑиÑÑÑ ‡ ник питР° ниÑ, ÐÐ »ÐµÐºÑ‚Ñ € Ð¾Ñ ÐµÑ‚ÑŒ]} Sistema.Colecciones. Generic.KeyValuePair
  • [1] {[Ð¡Ð¾Ñ Ñ‚Ð¾Ñ Ð½Ð¸Ðµ Ð ± Ð ° Ñ‚Ð ° Ñ € ей, Ð ÐµÑ ‚Ð ± Ð ° Ñ‚Ð ° Ñ € еи]} System.Collections.Generic.KeyValuePair
  • [2] {[ПоР»Ð½Ð¾Ðµ Ð²Ñ € ÐµÐ¼Ñ Ñ € Ð ° Ð ± оты Ð¾Ñ ‚Ð ± Ð ° Ñ‚Ð ° Ñ € ей, еиР· Ð²ÐµÑ Ñ‚Ð½Ð¾]} System.Collections. Generic.KeyValuePair
  • [3] {[ÐžÑ Ñ‚Ð ° Ð²ÑˆÐµÐµÑ Ñ Ð²Ñ € ÐµÐ¼Ñ Ñ € Ð ± Ð¾Ñ‚Ñ ‹Ð¾Ñ‚ Ð ± Ð ° Ñ‚Ð ° Ñ € µÐ¹ РвиеÑÐо System.Collections.Generic.KeyValuePair

y las tables["power management"]["Текущий Ð¸Ñ Ñ‚Ð¾Ñ‡Ð½Ð¸Ðº Ð¿Ð¸Ñ‚Ð°Ð½Ð¸Ñ "] devuelve:

"Ðл ÐµÐºÑ‚Ñ € Ð¾Ñ ÐµÑ‚ÑŒ "

Para iterar puedes hacer:

foreach(var tableName in tables.Keys)
{
    var table = tables[tableName];
    foreach(var key in table.Keys)
    {
        string value = table[key];
        Debug.Print(tableName + "/" + key + "/" + value);
    }
}



Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué