Problemi con HtmlAgilityPack

c# html-agility-pack

Domanda

Ho padroneggiato HtmlAgilityPack. Sto cercando di ottenere i dati da una pagina precaricata. Vale a dire: c'è una pagina 1.htm. Voglio ottenere il valore dalla tabella di fronte alla linea "Sistema operativo". (il documento stesso è allegato). Lo faccio:

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

In generale, è necessario estrarre molte informazioni dal file, ma penso che se si ottiene una linea, quindi ulteriormente per analogia.

La linea richiesta era la seguente:

 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;
            }

Ma questa opzione è "sulla fronte". Se non si modifica la struttura del mio documento. E come è possibile con l'aiuto della ricerca non ha ancora capito.

File

Risposta accettata

Ciò restituirà un dizionario di tabelle per nome. Ogni tabella è un dizionario con la prima colonna come chiave e il secondo come valore.

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

}

Ad esempio, tables["power management"] restituisce 4 voci:

  • [0] {Ð ¢ ÐμÐºÑƒÑ ‰ ий Ð¸Ñ Ñ,Ð¾Ñ ‡ Ð Ð Ñ ÐμкÑ,Ñ € Ð¾Ñ ÐμÑ,ÑŒ]} Sistema.Collezioni. Generic.KeyValuePair
  • [1] {[Ð¡Ð¾Ñ Ñ,Ð¾Ñ Ð½Ð¸Ðμ Ð ± Ð ° Ñ,Ð ° Ðμй, Ð ÐμÑ, Ð ± Ð ° Ñ,Ð ° Ñ € Ðμи]} System.Collections.Generic.KeyValuePair
  • [2] {[ПоР»Ð½Ð¾Ðμ Ð²Ñ € Ð ± Ð ° Ñ,Ð ° Ñ € Ðμй, Ð ÐμиР· вÐμÑ Ñ,но]} Sistema.Collezioni. Generic.KeyValuePair
  • [3] {[ÐžÑ Ñ,Ð ° вÑÐμÐμÑ Ñ Ð²Ñ, Ð ± Ð ° Ñ,Ð ° Ñ € Ðμй, Ð ÐμиР· вÐμÑ Ñ,но]} System.Collections.Generic.KeyValuePair

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

"Ðл ÐμкÑ,Ñ € Ð¾Ñ ÐμÑ,ÑŒ "

Per l'iterazione puoi fare:

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


Related

Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché
Autorizzato sotto: CC-BY-SA with attribution
Non affiliato con Stack Overflow
È legale questo KB? Sì, impara il perché