Проблема с HTMLAgilityPack разбора HTML с использованием C #

c# html-agility-pack xpath

Вопрос

Я просто пытаюсь узнать о HTMLAgilityPack и XPath, я пытаюсь получить список компаний (HTML-ссылок) с сайта NASDAQ;

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;

//*table[@id='indu_table']/tbody/tr[*]/td/b/a

При запуске моего проекта я получаю исключение xpath, которое было бы необработанным, поскольку оно является недопустимым токеном.

Я немного не уверен, что с ним не так, я попытался поместить номер в tr [*] раздел выше, но я все равно получаю ту же ошибку.

Я смотрел на это в течение последнего часа, это что-то простое?

благодаря

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

Поскольку данные поступают из javascript, вам нужно проанализировать javascript, а не 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());
  }
}

Чтобы объяснить немного более подробно, данные поступают из одного большого массива javascript на странице var table_body = [... Каждый запас является одним из элементов массива и является самим массивом.

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

Таким образом, анализируя массив и беря первый элемент и добавляя исправление, мы получаем тот же результат, что и javascript.


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

Если вы посмотрите на источник страницы для этого URL-адреса, на самом деле нет элемента с id=indu_table . Кажется, он генерируется динамически (т. Е. В javascript); html, который вы получаете при загрузке непосредственно с сервера, не будет отражать ничего, что было изменено клиентом. Вероятно, поэтому он не работает.



Related

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