Problem mit HTMLAgilityPack, das HTML mit C # analysiert

c# html-agility-pack xpath

Frage

Ich versuche nur etwas über HTMLAgilityPack und XPath zu lernen, ich versuche eine Liste von (HTML Links) Unternehmen von der NASDAQ Website zu bekommen;

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

Ich habe derzeit den folgenden Code;

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

Ich habe ein XPath-Addon für Chrome verwendet, um den XPath von zu erhalten;

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

Wenn ich mein Projekt ausführe, erhalte ich eine unbehandelte Xpath-Ausnahme darüber, dass es ein ungültiges Token ist.

Ich bin ein wenig unsicher, was damit nicht stimmt, ich habe versucht, eine Zahl in den Abschnitt tr [*] zu setzen, aber ich bekomme immer noch denselben Fehler.

Ich habe mir das in der letzten Stunde angeschaut. Ist es etwas Einfaches?

Vielen Dank

Akzeptierte Antwort

Da die Daten von Javascript stammen, müssen Sie das Javascript und nicht das HTML analysieren, daher hilft das Agility Pack nicht so viel, aber es macht die Dinge etwas einfacher. Im Folgenden wird beschrieben, wie Agility Pack und Newtonsoft JSON.Net verwendet werden können , um das Javascript zu analysieren.

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

Um etwas detaillierter zu erklären, stammen die Daten von einem großen Javascript-Array auf der Seite var table_body = [... Jeder Bestand ist ein Element im Array und ist selbst ein Array.

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

Also, indem wir das Array analysieren und das erste Element nehmen und die Fix-URL anhängen, erhalten wir das gleiche Ergebnis wie das Javascript.


Beliebte Antwort

Wenn Sie sich die id=indu_table für diese URL ansehen, gibt es kein Element mit id=indu_table . Es scheint dynamisch (dh in Javascript) generiert zu werden; Der HTML-Code, den Sie beim Laden direkt vom Server erhalten, spiegelt nichts wider, was vom Client-Skript geändert wurde. Dies ist wahrscheinlich der Grund, warum es nicht funktioniert.



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum