HtmlAgilityPack을 사용하여 웹 페이지에서 데이터 추출 중

c# html-agility-pack web

문제

나는 하나의 데이터를 추출하려고한다.
http://www.dsebd.org/displayCompany.php?name=NBL
I 첨부 영상에서 필요한 필드를 보였다하는의 XPath : / HTML / 바디 / [표 2] / TBODY / TR / TD [2] / 표 / TBODY / TR [3] / TD 1 / P 1 / 표 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 및 사용중인 도구는 브라우저에 의해 수정 된 dom 트리에서 작동합니다 (모두 단일 html 노드로 묶음, 일부 tbody 추가 등).

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에 코드를 래핑하십시오.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.