// Uses Internet Explorer to programmatically retrieve a stock quote // It shows the techniques of // (a) waiting for a page load to complete, // This involves registering an event listener to the web browser, // and listening to events until the top level frame sends // a DocumentComplete event. // and // (b) examining the contents of a page after it has been loaded. // There is no general mechanism for this. This is done on // an ad-hoc basis. The web page source needs to be examined // for patterns that can help in locating the item of interest. // Below are some examples of how such patterns can be used. // WARNING: This sample is provided AS IS. The web-sites included // here are as examples only. The web-site layouts may change, making // the code below invalid at any time. import iexplorer.InternetExplorer; import iexplorer.IWebBrowserApp; import mshtml.IHTMLDocument2; import mshtml.IHTMLElementCollection; import mshtml.IHTMLElement; import ezjcom.JComVariant; import ezjcom.JComObject; import java.io.BufferedReader; import java.io.InputStreamReader; public class StockQuote { public static void main(String args[]) { IWebBrowserApp app = null; try { // Instantiate an InternetExplorer InternetExplorer ie = new InternetExplorer(); // Get IWebBrowserApp app = ie.getIWebBrowserApp(); // HINT: While developing, make the browser visible!! // app.setVisible( true ); // NOTE: When browser is not visible, the following workaround must // be added for an Internet Explorer bug (http://support.microsoft.com/kb/259935) // Remove it or comment it out if setting the browser visible. app.setLeft( - app.getWidth()); // If IE is trying to load any default pages, stop it. app.Stop(); // Attach the events listener. WebLoadListener webLoadListener = new WebLoadListener(); ie.addJComEventListener( webLoadListener ); // Get a buffered reader to read user input. BufferedReader in = new BufferedReader( new InputStreamReader( System.in )); // Note: The same instance of IE is used for all quotes, // to avoid the delay of IE initialization. for (;;) { System.out.println( " 1) MSN Money Stock Quote" ); System.out.println( " 2) Bloomberg Stock Quote" ); System.out.println( " 3) Google Finance Stock Quote" ); System.out.println( " 4) Yahoo Finance Stock Quote" ); System.out.println( " 5) Quit" ); System.out.print( "Enter Command Number: " ); String cmd = in.readLine().trim(); if ( cmd.equals( "5" )) break; if ( ! ( cmd.equals( "1" ) || cmd.equals( "2" ) || cmd.equals( "3" ) || cmd.equals( "4" ))) continue; System.out.print( "Enter Stock Symbol> " ); // Get Stock Symbol String stock = in.readLine().trim(); if ( stock.equals("")) continue; String url = ""; if ( cmd.equals( "1" )) url = "http://moneycentral.msn.com/detail/stock_quote?Symbol="; else if ( cmd.equals( "2" )) url = "http://www.bloomberg.com/apps/quote?ticker="; else if ( cmd.equals( "3" )) url = "http://finance.google.com/finance?q="; else if ( cmd.equals( "4" )) url = "http://finance.yahoo.com/q?s="; url += stock; if ( cmd.equals( "2" ) && stock.indexOf( ':' ) < 0 ) url += ":US"; // Tell browser to load the Stock Quote from website, and wait for load completion. System.out.println( "Retrieving " + url ); webLoadListener.initialize(); synchronized ( webLoadListener ) { app.Navigate( url ); webLoadListener.wait(); } System.out.println( "Examining contents of " + url ); // Now retrieve and examine the contents of the website. IHTMLDocument2 doc = (IHTMLDocument2) app.getDocument().JComCoerceObjectToAnotherType( IHTMLDocument2.class ); IHTMLElementCollection all = doc.getAll(); // Process the collection, depending upon the web-site. String price = null; String source = null; // Ad-hoc parsing of the four sites of interest. if ( cmd.equals( "1" )) { // MSN Money // For MSN Money, the stock price is the first "s1" element. source = "MSN Money"; for ( int i = 0; i < all.getLength(); i++ ) { JComObject obj = all.item( new JComVariant( i )); IHTMLElement elem = (IHTMLElement) obj.JComCoerceObjectToAnotherType( IHTMLElement.class ); if ( "s1".equals( elem.getClassName())) { price = elem.getInnerText().trim(); break; } } } else if ( cmd.equals( "2" )) { // Bloomberg // For Bloomberg, the stock price is in the second "QuoteTableData" style element. source = "Bloomberg"; int count = 0; for ( int i = 0; i < all.getLength(); i++ ) { JComObject obj = all.item( new JComVariant( i )); IHTMLElement elem = (IHTMLElement) obj.JComCoerceObjectToAnotherType( IHTMLElement.class ); if ( "QuoteTableData".equals( elem.getClassName())) { if ( ++count == 2 ) { price = elem.getInnerText().trim(); break; } } } } else if ( cmd.equals( "3" )) { // Google Finance // For Google Finance, the stock price is in the first "SPAN" that has a non-null ID. source = "Google Finance"; for ( int i = 0; i < all.getLength(); i++ ) { JComObject obj = all.item( new JComVariant( i )); IHTMLElement elem = (IHTMLElement) obj.JComCoerceObjectToAnotherType( IHTMLElement.class ); if ( elem.getTagName().equalsIgnoreCase( "SPAN" ) && elem.getId() != null ) { price = elem.getInnerText().trim(); break; } } } else if ( cmd.equals( "4" )) { // Yahoo Finance // For Yahoo Finance, the stock price is in the second "SPAN" with an id // that ends with an underscore and the stock name. source = "Yahoo Finance"; String stkLwr = "_" + stock.toLowerCase(); int count = 0; for ( int i = 0; i < all.getLength(); i++ ) { JComObject obj = all.item( new JComVariant( i )); IHTMLElement elem = (IHTMLElement) obj.JComCoerceObjectToAnotherType( IHTMLElement.class ); if ( elem.getTagName().equalsIgnoreCase( "SPAN" ) && elem.getId() != null && elem.getId().toLowerCase().endsWith( stkLwr )) { if ( ++count == 2 ) { price = elem.getInnerText().trim(); break; } } } } System.out.println(); if ( price == null ) System.out.println( source + " could not find a price for " + stock ); else System.out.println( "According to " + source + ", the last price of " + stock + " was " + price ); System.out.println(); } } catch (Exception ex) { ex.printStackTrace(); } finally { if ( app != null ) try { app.Quit(); } catch (Exception ex) {} } System.exit( 0 ); } }