Introduction
In this week's companion article on the Radar blog, I discuss a feature of the elmcity service that enables curators to find web pages that mention recurring events. The elmcity service searches Google and Bing for a family of queries like every 2nd Tuesday at 9PM. But you can use the core search methods for any queries against the JSON APIs exposed by Google and Bing.
Encapsulating Google's search API
Here's a simple class to represent a search result along with its source, which might be Google or Bing or both.
public class SearchResult
{
public string url;
public string title;
public string content;
public FindingEngine engine;
public enum FindingEngine { google, bing, google_and_bing };
public SearchResult(string url, string title, string content, FindingEngine engine)
{
this.url = url;
this.title = title;
this.content = content;
this.engine = engine;
}
}
Both searchers return lists of these objects. Here's the Google searcher:
public static List<SearchResult> GoogleSearch(string search_expression,
Dictionary<string, object> stats_dict)
{
var url_template = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&rsz=large \
&safe=active&q={0}&start={1}";
Uri search_url;
var results_list = new List<SearchResult>();
int[] offsets = { 0, 8, 16, 24, 32, 40, 48 };
foreach (var offset in offsets)
{
search_url = new Uri(string.Format(url_template, search_expression, offset));
var page = new WebClient().DownloadString(search_url);
JObject o = (JObject)JsonConvert.DeserializeObject(page);
var results_query =
from result in o["responseData"]["results"].Children()
select new SearchResult(
url: result.Value<string>("url").ToString(),
title: result.Value<string>("title").ToString(),
content: result.Value<string>("content").ToString(),
engine: SearchResult.FindingEngine.google
);
foreach (var result in results_query)
results_list.Add(result);
}
return results_list;
}
The JSON deserializer, JsonConvert.DeserializeObject, is part of James Newton-King's Json.NET library. Why use it here, rather than one of the deserializers built into the .NET Framework? Those deserializers -- JavascriptSerializer (in System.Web.Extensions) and DataContractJsonSerializer (in System.Runtime.Serialization.Web) expect to map JSON to .NET types. But here I have no other need for those .NET types, and I don't want to bother to define them, I just want to parse some values out of the JSON. Json.NET is a convenient way to do that.
Encapsulating Bing's search API
Here's the Bing searcher:
public static List<SearchResult> BingSearch(string search_expression, Dictionary<string, object> stats_dict)
{
var url_template = "http://api.search.live.net/json.aspx?AppId=8F9B...1CF6&Market=en-US& \
Sources=Web&Adult=Strict&Query={0}&Web.Count=50";
var offset_template = "&Web.Offset={1}";
var results_list = new List<SearchResult>();
Uri search_url;
int[] offsets = { 0, 50, 100, 150 };
foreach (var offset in offsets)
{
if (offset == 0)
search_url = new Uri(string.Format(url_template, search_expression));
else
search_url = new Uri(string.Format(url_template + offset_template, search_expression, offset));
var page = new WebClient().DownloadString(search_url);
JObject o = (JObject)JsonConvert.DeserializeObject(page);
var results_query =
from result in o["SearchResponse"]["Web"]["Results"].Children()
select new SearchResult
(
url: result.Value<string>("Url").ToString(),
title: result.Value<string>("Title").ToString(),
content: result.Value<string>("Description").ToString(),
engine: SearchResult.FindingEngine.bing
);
foreach (var result in results_query)
results_list.Add(result);
}
return results_list;
}

Help





