Essayer d'extraire des données d'une page Web en utilisant HtmlAgilityPack

c# html-agility-pack web

Question

J'essaie d'extraire une seule donnée de
http://www.dsebd.org/displayCompany.php?name=NBL
J'ai montré le champ requis dans la photo jointe pour laquelle Xpath: / html / body / table [2] / tbody / tr / td [2] / table / tbody / tr [3] / td 1 / p 1 / table 1 / tbody / tr / td 1 / table / tbody / tr [2] / td [2] / font

Erreur: une exception se produit et aucune donnée n'a été trouvée à l'aide de ce Xpath. "Une exception non gérée du type 'System.Net.WebException' s'est produite dans HtmlAgilityPack.dll"

entrez la description de l'image ici

Code source:

static void Main(string[] args)
    {
        /************************************************************************/
        string tickerid = "Bse_Prc_tick";
        HtmlAgilityPack.HtmlDocument doc = new   HtmlWeb().Load(@"http://www.dsebd.org/displayCompany.php?name=NBL", "GET");

        if (doc != null)
        {
            // Fetch the stock price from the Web page
            string stockprice = doc.DocumentNode.SelectSingleNode(string.Format("./html/body/table[2]/tbody/tr/td[2]/table/tbody/tr[3]/td1/p1/table1/tbody/tr/td1/table/tbody/tr[2]/td[2]/font", tickerid)).InnerText;
            Console.WriteLine(stockprice);
        }
        Console.WriteLine("ReadKey Starts........");
        Console.ReadKey();
}

Réponse acceptée

Eh bien, j'ai vérifié. Les XPaths que nous utilisions sont tout simplement incorrects. Le vrai plaisir commence lorsque vous essayez de trouver où se trouve l'erreur.

Il suffit de consulter le code source de la page que vous utilisez, en dehors de nombreuses erreurs qui empêchent XPath de contenir plusieurs balises HTML ...

Les outils de développement de Chrome, ainsi que l’outil que vous utilisiez, fonctionnent sur l’arborescence des domaines corrigée par le navigateur (tous regroupés dans un seul noeud html, y compris un tbody, etc.).

Comme la structure html est simplement cassée, l'analyse HtmlAgilityPack est devenue.

Avec la situation actuelle, vous pouvez utiliser RegExp ou simplement rechercher des éléments connus dans le source (ce qui est beaucoup plus rapide, mais moins agile).

Par exemple:

...
using System.Net; //required for Webclient
...
        class Program
        {
            //entry point of console app
            static void Main(string[] args)
            {
                // url to download
                // "var" means I am too lazy to write "string" and let compiler decide typing
                var url = @"http://www.dsebd.org/displayCompany.php?name=NBL";

                // creating object in using makes Garbage Collector delete it when using block ends, as opposed to standard cleaning after whole function ends
                using (WebClient client = new WebClient()) // WebClient class inherits IDisposable
                {

                    // simply download result to string, in this case it will be html code
                    string htmlCode = client.DownloadString(url);
                    // cut html in half op position of "Last Trade:"
                    // searching from beginning of string is easier/faster than searching in middle
                    htmlCode = htmlCode.Substring(
                        htmlCode.IndexOf("Last Trade:")
                        );
                    // select from .. to .. and then remove leading and trailing whitespace characters
                    htmlCode = htmlCode.Substring("2\">", "</font></td>").Trim();
                    Console.WriteLine(htmlCode);
                }
                Console.ReadLine();
            }
        }
        // http://stackoverflow.com/a/17253735/3147740 <- copied from here
        // this is Extension Class which adds overloaded Substring() I used in this code, it does what its comments says
        public static class StringExtensions
        {
            /// <summary>
            /// takes a substring between two anchor strings (or the end of the string if that anchor is null)
            /// </summary>
            /// <param name="this">a string</param>
            /// <param name="from">an optional string to search after</param>
            /// <param name="until">an optional string to search before</param>
            /// <param name="comparison">an optional comparison for the search</param>
            /// <returns>a substring based on the search</returns>
            public static string Substring(this string @this, string from = null, string until = null, StringComparison comparison = StringComparison.InvariantCulture)
            {
                var fromLength = (from ?? string.Empty).Length;
                var startIndex = !string.IsNullOrEmpty(from)
                    ? @this.IndexOf(from, comparison) + fromLength
                    : 0;

                if (startIndex < fromLength) { throw new ArgumentException("from: Failed to find an instance of the first anchor"); }

                var endIndex = !string.IsNullOrEmpty(until)
                ? @this.IndexOf(until, startIndex, comparison)
                : @this.Length;

                if (endIndex < 0) { throw new ArgumentException("until: Failed to find an instance of the last anchor"); }

                var subString = @this.Substring(startIndex, endIndex - startIndex);
                return subString;
            }
        }

Réponse populaire

Enveloppez votre code dans try-catch pour obtenir plus d'informations sur l'exception.




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