A couple months ago, I implemented wrappers for the Google Charts and Google Translate API's. Today, I'd like to implement a wrapper for Google Search.
Search
First, we should build a word that, given a query, returns a URL to retrieve Google Search results (formatted as JSON):
: search-url ( query -- url ) URL" http://ajax.googleapis.com/ajax/services/search/web" "1.0" "v" set-query-param swap "q" set-query-param "8" "rsz" set-query-param "0" "start" set-query-param ;
We can define a tuple class to hold the attributes every search result should have:
TUPLE: search-result cacheUrl GsearchResultClass visibleUrl title content unescapedUrl url titleNoFormatting ;
Using some code to set attributes dynamically, we can perform a Google Search, and parse the results into a sequence of search-result
objects.
: http-search ( query -- results ) search-url http-get nip json> { "responseData" "results" } [ swap at ] each [ \ search-result from-slots ] map ;
Display
We can build some simple words that can be used to format the output of a search:
: write-heading ( str -- ) H{ { font-size 14 } { background COLOR: light-gray } } format nl ; : write-title ( str -- ) H{ { foreground COLOR: blue } } format nl ; : write-content ( str -- ) 60 wrap-string print ; : write-url ( str -- ) dup >url H{ { font-name "monospace" } { foreground COLOR: dark-green } } [ write-object ] with-style nl ;
And then create a word to perform a search and display the results. If you are using my webbrowser vocabulary, you can open the URL's in a webbrowser directly from Factor.
: http-search. ( query -- ) [ "Search results for '%s'" sprintf write-heading nl ] [ http-search ] bi [ { [ titleNoFormatting>> write-title ] [ content>> write-content ] [ unescapedUrl>> write-url ] } cleave nl ] each ;
Try it out
If everything works correctly, you should be able to perform a search in the Listener (e.g., searching for "factor"):
Some things we might do to improve this:
- add paging, to the next or previous page of search results
- highlight in bold the searched words in the content
- unescape the HTML entities in the content
- build a lightweight GUI to render the results
The code for this is on my Github.
This is a much more elegant method to manipulate and set query parameters. I was using some ugly split code before.
ReplyDeleteThanks!