C #을 사용하여 HTML을 구문 분석하는 HTMLAgilityPack 관련 문제

c# html-agility-pack xpath

문제

HTMLAgilityPack과 XPath에 대해 배우려고하고 있는데, NASDAQ 웹 사이트에서 (HTML Links) 회사의 목록을 얻으려고합니다.

http://www.nasdaq.com/quotes/nasdaq-100-stocks.aspx

현재 다음 코드가 있습니다.

HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();

        // Create a request for the URL.        
        WebRequest request = WebRequest.Create("http://www.nasdaq.com/quotes/nasdaq-100-stocks.aspx");
        // Get the response.
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        // Get the stream containing content returned by the server.
        Stream dataStream = response.GetResponseStream();
        // Open the stream using a StreamReader for easy access.
        StreamReader reader = new StreamReader(dataStream);
        // Read the content.
        string responseFromServer = reader.ReadToEnd();
        // Read into a HTML store read for HAP
        htmlDoc.LoadHtml(responseFromServer);

        HtmlNodeCollection tl = htmlDoc.DocumentNode.SelectNodes("//*[@id='indu_table']/tbody/tr[*]/td/b/a");
        foreach (HtmlAgilityPack.HtmlNode node in tl)
        {
            Debug.Write(node.InnerText);
        }            

        // Cleanup the streams and the response.
        reader.Close();
        dataStream.Close();
        response.Close();

XPath를 얻으려면 Chrome 용 XPath 애드온을 사용했습니다.

HtmlAgilityPack.HtmlDocument htmlDoc = new HtmlAgilityPack.HtmlDocument();

        // Create a request for the URL.        
        WebRequest request = WebRequest.Create("http://www.nasdaq.com/quotes/nasdaq-100-stocks.aspx");
        // Get the response.
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        // Get the stream containing content returned by the server.
        Stream dataStream = response.GetResponseStream();
        // Open the stream using a StreamReader for easy access.
        StreamReader reader = new StreamReader(dataStream);
        // Read the content.
        string responseFromServer = reader.ReadToEnd();
        // Read into a HTML store read for HAP
        htmlDoc.LoadHtml(responseFromServer);

        HtmlNodeCollection tl = htmlDoc.DocumentNode.SelectNodes("//*[@id='indu_table']/tbody/tr[*]/td/b/a");
        foreach (HtmlAgilityPack.HtmlNode node in tl)
        {
            Debug.Write(node.InnerText);
        }            

        // Cleanup the streams and the response.
        reader.Close();
        dataStream.Close();
        response.Close();

내 프로젝트를 실행할 때 유효하지 않은 토큰 인 xpath 처리되지 않은 예외가 발생합니다.

나는 그것이 무엇인지 잘못 알고 있지만 위의 tr [*] 섹션에 숫자를 넣으려고했지만 여전히 같은 오류가 발생합니다.

지난 1 시간 동안 이걸보고 있었는데, 뭐 간단한가요?

감사

수락 된 답변

데이터가 자바 스크립트에서 나오기 때문에 당신은 HTML이 아닌 자바 스크립트를 파싱해야합니다. 그래서 Agility Pack은 그다지 도움이되지는 않지만 좀 더 쉽게 만듭니다. 다음은 Agility Pack 및 Newtonsoft JSON.Net 을 사용하여 Javascript를 구문 분석하는 방법입니다.

HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.Load(new WebClient().OpenRead("http://www.nasdaq.com/quotes/nasdaq-100-stocks.aspx"));
List<string> listStocks = new List<string>();
HtmlNode scriptNode = htmlDoc.DocumentNode.SelectSingleNode("//script[contains(text(),'var table_body =')]");
if (scriptNode != null)
{
  //Using Regex here to get just the array we're interested in...
  string stockArray = Regex.Match(scriptNode.InnerText, "table_body = (?<Array>\\[.+?\\]);").Groups["Array"].Value;
  JArray jArray = JArray.Parse(stockArray);
  foreach (JToken token in jArray.Children())
  {
    listStocks.Add("http://www.nasdaq.com/symbol/" + token.First.Value<string>().ToLower());
  }
}

좀 더 자세히 설명하기 위해 데이터는 페이지의 하나의 큰 자바 스크립트 배열에서 가져옵니다. var table_body = [... 각 주식은 배열의 한 요소이며 배열 자체입니다.

["ATVI", "Activision Blizzard, Inc", 11.75, 0.06, 0.51, 3058125, 0.06, "N", "N"]

따라서 배열을 파싱하고 첫 번째 요소를 가져 와서 수정 URL을 추가하면 자바 스크립트와 같은 결과를 얻게됩니다.


인기 답변

해당 URL의 페이지 소스를 보면 실제로 id=indu_table 요소는 없습니다. 동적으로 (즉 자바 스크립트에서) 생성 된 것으로 보입니다. 서버에서 직접로드 할 때 얻는 html은 클라이언트 스크립트에 의해 변경된 내용을 반영하지 않습니다. 아마도 이것이 작동하지 않는 이유 일 것입니다.




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