Попытка извлечь данные с веб-страницы с помощью HtmlAgilityPack

c# html-agility-pack web

Вопрос

Я пытаюсь извлечь данные из
http://www.dsebd.org/displayCompany.php?name=NBL
Я показал требуемое поле в прикрепленном изображении, для которого 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

Ошибка: происходит исключение, и данные не найдены с использованием этого Xpath. «Необработанное исключение типа« System.Net.WebException »произошло в HtmlAgilityPack.dll"

введите описание изображения здесь

Исходный код:

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

Принятый ответ

Ну, я проверил. XPath, которые мы использовали, просто неверны. Настоящее веселье начинается, когда вы попытаетесь найти, где ошибка.

Просто проверьте исходный код страницы, которую вы используете, помимо многочисленных ошибок, которые мешают XPath, он даже содержит несколько тегов HTML ...

Chrome Dev Tools и инструмент, который вы использовали, работает на дереве, исправленном браузером (все упаковано в один узел html, добавлено несколько тел и т. Д.).

Поскольку html-структура просто разбита, таким образом, стал синтаксический анализ HtmlAgilityPack.

В такой ситуации вы можете либо использовать RegExp, либо просто искать известные элементы в источнике (что намного быстрее, но менее гибко).

Например:

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

Популярные ответы

Оберните свой код в try-catch, чтобы получить дополнительную информацию об исключении.



Related

Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow
Лицензировано согласно: CC-BY-SA with attribution
Не связан с Stack Overflow