Utilisation de HtmlAgilityPack pour obtenir des données spécifiques en C # et les sérialiser en json

c# html html-agility-pack json visual-studio

Question

J'ai téléchargé un code source HTML et j'essaie d'en extraire des données pour le sérialiser dans un fichier "json".

Il s'agit du fichier source html: https://drive.google.com/file/d/0BzweTZsfeoxMTWk2LVdnYTJMRUE/view?usp=sharing.

Dans le code html, je souhaite collecter des données à partir de "2" groupes.

Pour le moment, j'ai réussi à insérer le code dans ces "2" groupes et à l'afficher dans deux panneaux à l'aide d'étiquettes. Mon code est comme jachères:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HtmlAgilityPack;

namespace Parser_Test_1._0
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.Load(@"C:...\bin\Debug\xbFrSourceCode.txt");

            string datacollected1 = doc.DocumentNode.SelectNodes("//*[@id=\"favoritesContent\"]/div[2]/div[2]/ul")[0].InnerHtml;
            string datacollected2 = doc.DocumentNode.SelectNodes("//*[@id=\"friendsContent\"]/div[2]/div[2]")[0].InnerHtml;
            label1.Text = datacollected1;
            label2.Text = datacollected2;
        }      

    }
}

De ce deux groupes je souhaite rassembler les utilisateurs dans eux et pour chaque utilisateur, leurs données respectives pour les sérialiser dans un fichier JSON.

Chaque utilisateur est séparé avec <li ...></li>

Pour chaque utilisateur que je souhaite obtenir:

  • Gamertag: data-gamertag="this is the gamertag"
  • Gamerpic: c'est dans class="gamerpicWrapper" le src="this is the gamerpic"
  • Nom réel: <div class="realName">this is the realname</div>
  • PrimaryInfo: <div class="primaryInfo">this is the primaryinfo</div>
  • isOnline: <div class="statusIcon"> s'il y a du code ici, alors dans le fichier json cette valeur sera vraie </div>

Voici un exemple du format de fichier "json" souhaité (notez que le code suivant est probablement mal écrit):

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using HtmlAgilityPack;

namespace Parser_Test_1._0
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.Load(@"C:...\bin\Debug\xbFrSourceCode.txt");

            string datacollected1 = doc.DocumentNode.SelectNodes("//*[@id=\"favoritesContent\"]/div[2]/div[2]/ul")[0].InnerHtml;
            string datacollected2 = doc.DocumentNode.SelectNodes("//*[@id=\"friendsContent\"]/div[2]/div[2]")[0].InnerHtml;
            label1.Text = datacollected1;
            label2.Text = datacollected2;
        }      

    }
}

J'apprécierais beaucoup si quelqu'un pouvait me montrer comment faire cela.

Réponse populaire

Le code suivant montre une utilisation appropriée de xpath et HAP. L'utilisation de xpath peut être simplifiée, mais vous m'avez donné un fichier HTML de 4k et je n'ai pas envie d'apprendre la structure de tout cela. Cependant, le code obtient tout ce que vous voulez en tant que variables. À présent, votre travail consiste à intégrer une structure JSON, mais si vous ne connaissez pas JSON, envisagez d’utiliser XML.

        HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
        doc.OptionFixNestedTags = true;
        doc.Load("damn.html");

        //First off we find the nodes we want to collect data from. Note that we are only looking for a singlenode compared to your code where you find all nodes
        //this could be cut down to selectnodes where we take all <li> tages with each div tag. But for simplicity.
        HtmlNodeCollection favoritesContent = doc.DocumentNode.SelectNodes("//div[@id='favoritesContent']/div[@class='personListWrapper']/div[@class='gamerList']/ul//li");

        foreach (HtmlNode x in favoritesContent)
        {
            //here we find the gamertag which is an attribute in <li> if <li> does not have that value
            //it will then return the deault value ""(empty string as specified)
            string gamerTag = x.GetAttributeValue("data-gamertag", "");
            HtmlNode temp = x.SelectSingleNode("./a[@class='gamerpicWrapper']/*/img[@class='favorite']");
            string srcOnPic = temp.GetAttributeValue("src", "not found");
            string realName = x.SelectSingleNode("./descendant::*//div[@class='realName']").InnerText;
            string primaryInfo = x.SelectSingleNode("./descendant::*//div[@class='primaryInfo']").InnerText;

            if (0 < x.SelectSingleNode("./div[@class='statusIcon']").InnerHtml.Length)
            {
                bool online = true;

            }
        }



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi