Tue, Mar 28, 2006 3-minute read

One of the scripts I like the most in my toolbox is the one that gives me answers to questions from the command line.

For the past 2 years or so, Encarta has offered an extremely useful “Instant Answers” feature.  It’s since been integrated into MSN Search, as well as a wildly popular Chat Bot.  MoW showed how to use that feature through a Monad IM interface (via the Conversagent bot,) but we can do a great job with good ol’ screen scraping.

``````[C:\temp]
PS:51 > Get-Answer "What is the population of China?"

China Population, total: 1,313,973,700
2006 estimate
United States Census International Programs Center

[C:\temp]

5^(e ^( x^2))=50 : x=-0.942428

[C:\temp]

lean bacon

[C:\temp]
PS:54 > Get-Answer "How many calories in an apple?"

Apples calories
1.0 cup, quartered or chopped has 65 calories
1.0 NLEA serving has 80 calories
1.0 small (2-1/2" dia) (approx 4 per lb) has 55 calories
1.0 medium (2-3/4" dia) (approx 3 per lb) has 72 calories
1.0 large (3-1/4" dia) (approx 2 per lb) has 110 calories
1.0 cup slices has 57 calories
USDA

[C:\temp]
PS:55 > Get-Answer "How many inches in a light year?"

1 lightyear = 372,461,748,226,857,000 inches
``````

Here is the script, should you require your own command-line oracle:

(Edit 4/2021: Screen scraping is a PITA and this script has broken about a million times since this post was written. Feel free to use it for inspiration, but this code won’t work verbatim.)

``````## Get-Answer.ps1

## Example:
##    Get-Answer “What is the population of China?”

function Main
{
## Load the System.Web.HttpUtility DLL, to let us URLEncode

## Get the web page into a single string with newlines between
## the lines.
\$encoded = [System.Web.HttpUtility]::UrlEncode(\$question)

## Get the answer with annotations
\$endIndex = \$text.IndexOf('<div id="results">')

## If we found a result, then filter the result
if((\$startIndex -ge 0) -and (\$endIndex -ge 0))
{
\$partialText = \$text.Substring(\$startIndex, \$endIndex - \$startIndex)

## Very fragile, voodoo screen scraping here
\$partialText = \$partialText -replace '<span class=“answer_feedback”>.*Is this useful\?',"`n"
\$partialText = \$partialText -replace '<span class=“attr…">',"`n"
\$partialText = \$partialText -replace '<BR />',"`n"

\$partialText = clean-html \$partialText
\$partialText = \$partialText -replace "`n`n", "`n"

""
\$partialText.Trim()
}
else
{
""
}
}

## Clean HTML from a text chunk
function clean-html (\$htmlInput)
{
\$tempString = [Regex]::Replace(\$htmlInput, "<[^>]*>", "")
\$tempString.Replace("&nbsp&nbsp", "")
}

. Main
``````

[Edit: Updated to work with Windows Live Search, and with recent PowerShell builds.]