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