0

I am new to Java and I am trying to get the stock price , volume using JSOUP from finance.yahoo.com. https://finance.yahoo.com/quote/aapl

The numbers are in the div, table tags. For instance for AAPL: The Div is a class of "D(ib) W(1/2) ....." Then there is table ,class of W(100%) , then tbody, tr , td and and last is the span tag.

How can I get the value from the span tag,

amirg
  • 13
  • 2
  • 4
    Show what you've tried, there is multiple ex of Jsoup on this forum – azro Jul 30 '17 at 22:44
  • By the way, https://stackoverflow.com/questions/38355075/has-yahoo-finance-web-service-disappeared-api-changed-down-temporarily – OneCricketeer Jul 30 '17 at 23:13
  • Jsoup can be a good alternative to a REST/JSON API especially as HTML should be just another representation of the same data as delivered via JSON (though a bit more verbose). IMHO your question is pretty valid, especially as the yahoo-finance webservice seemed to be shut down. – Gerald Mücke Jul 30 '17 at 23:34

1 Answers1

0

You have to navigate from a unique point in the HTML structure to the data and try to rely only on "stable" information, i.e. the label for a field instead of the row count.

For instance let's take the Volume information. Analyze the HTML to get a uniquely identifiable element, i.e. the table with all the information. In this case it would be the div id="quote-summary".

From there you you could get the table and it's rows (tr). Now iterate to the table row, that contains a span with the text "Volume".

Once you found that row, get either the 2nd td or the next td sibling of the one with the "Volume"-span. This td contains your span with the Volume value.

String fieldToFiend = "Volume";

Document doc = Jsoup.connect("https://finance.yahoo.com/quote/aapl").get();

//get the root element
Element quoteSummary = doc.getElementById("quote-summary");
String value = quoteSummary.getElementsByTag("tr")
                           //iterate over the table rows inside
                           .stream()
                           //find the row with the first td/span containing the label
                           .filter(tr -> fieldToFiend.equals(tr.getElementsByTag("span").first().text()))
                           //get the 2nd td and it's span element
                           .map(tr -> tr.getElementsByTag("td")
                                        .first()
                                        .nextElementSibling()
                                        .getElementsByTag("span")
                                        .first()
                                        .text())
                           //get the first match
                           .findFirst()
                           .orElseThrow(NoSuchElementException::new);

System.out.println(value);
Gerald Mücke
  • 10,724
  • 2
  • 50
  • 67