|
Getting Yahoo! Stock Quotes with URL Access Scripting
Mac OS 8.6 includes a new system component called URL Access, which enables applications to upload and download data to and from the Internet without writing their own Internet protocol routines. Scripts can utilize URL Access services using URL Access Scripting, a scriptable application that also ships with Mac OS 8.6.
The following example AppleScript script retrieves a price quote for a particular stock symbol from Yahoo!'s Finance service. The script obtains a stock ticker symbol from the user (such as AAPL for Apple Computer), uses URL Access Scripting to post the form data to Yahoo!'s servers, parses the HTML page returned by Yahoo!'s servers, then displays the results.
There are dozens of ways this script could be made more elegant - and adding decent error handling would be a big one. This script is hard-coded to the HTML output returned by Yahoo!'s servers at the time the script was written; when Yahoo! changes their HTML markup, this script will break. Also, parsing the HTML page could be vastly simplified using third party utilities or OSAXen; however, the example script is designed to work with Mac OS 8.6's default AppleScript installation without any add-ons.
Please note this script is provided for informational and instructional purposes only; neither I nor TidBITS can assume any responsibility for its accuracy, compatibility with your system, or your satisfaction. You may distribute this script non-commercially in unaltered form; you may also use it as a basis for your own scripts, if you so desire.
You can download a text-only version (or a binhexed version) of this script that you can open and use in AppleScript's Script Editor application; if you just want to check out how the script works, an HTML version appears below. This script requires Mac OS 8.6.
--Geoff Duncan
Last updated
on run
set dlgReply to (display dialog "Get a Yahoo! stock quote for this symbol:" ¬
default answer "AAPL" buttons {"Get Quote", "Cancel"} default button 1 ¬
giving up after 30)
if button returned of dlgReply is "Cancel" then return
set daSymbol to allCaps(text returned of dlgReply)
-- make a temp file
set myFile to ((path to temporary items) as string) & "Stock Quote Script Temp"
-- fetch quote page
tell application "URL Access Scripting"
download "http://finance.yahoo.com/q" to file myFile replacing yes ¬
form data "s=" & daSymbol & "&d=v1"
quit
end tell
-- read HTML into a variable
open for access file myFile
set quoteHTML to (read file myFile to (get eof file myFile))
close access file myFile
-- find the lines with the last trade date and last price
-- Note: Yahoo changes their HTML format, this needs to change too.
set startTag to daSymbol & "</a></td>" & (ASCII character 10)
set daStart to (the offset of startTag in quoteHTML) + (the length of startTag)
set daCount to 1
copy "" to lastTrade
copy "" to lastPrice
repeat
if text from character (daStart + daCount) to (daStart + daCount + 1) ¬
of quoteHTML is "/t" then
if lastTrade is "" then
set lastTrade to text from character daStart to (daStart + daCount - 2) ¬
of quoteHTML
set daStart to daStart + daCount + 5
set daCount to 1
else
set lastPrice to text from character daStart to (daStart + daCount - 2) ¬
of quoteHTML
exit repeat
end if
end if
set daCount to daCount + 1
end repeat
--
tell application "Finder" to delete file myFile
set lastTrade to stripHTMLTags(lastTrade)
if lastTrade contains ":" then
-- markets are open, so it's a time
set lastTrade to "at " & lastTrade
else
-- martets are closed, so it's a date
set lastTrade to "on " & lastTrade
end if
display dialog "Yahoo says " & daSymbol & " last traded " & lastTrade & ¬
" at $" & stripHTMLTags(lastPrice) & "." with icon 1 ¬
buttons "OK" default button 1 giving up after 30
end run
on allCaps(daText)
-- very messy capitalization routine
copy "" to newText
repeat with i from 1 to the count of character in daText
set curChar to character i of daText
set curNum to ASCII number curChar
if (curNum > 96) and (curNum < 123) then
set newText to (newText & (ASCII character (curNum - 32))) as string
else
set newText to (newText & curChar) as string
end if
end repeat
return newText
end allCaps
on stripHTMLTags(HTML)
-- slow, and fails on bad HTML that doesn't use entities for < and >
-- but, requires no OSAXen and is good enough for now.
set intag to false
set newText to ""
repeat with i from 1 to count of character in HTML
set curChar to character i of HTML
if curChar is "<" then set intag to true
if not intag then set newText to (newText & curChar) as string
if curChar is ">" then set intag to false
end repeat
return newText
end stripHTMLTags
|
|