Because I have always assumed that Google would aggregate tracking information across its various web properties, I have long used
Scroogle for most of my web searches. It turns out I was right: every mail message you read, every search you perform, and every page you visit with a Google-served ad or analytics tracker is linked to your unique identity. With Google making Scroogle unreliable lately, I have given
Duck Duck Go (
implemented in a mixture of Perl and JavaScript) another look, and I have been pleasantly surprised: it gives pretty good results with an uncluttered interface and a
sane privacy policy.
It also has an easy-to-use API, without license keys or similar BS. While there are a couple of CPAN modules for this API, they're pretty heavy for such a simple task. Here's a simple script that, on Perl >= 5.14, has no non-core dependencies:
use JSON::PP;
use HTTP::Tiny;
sub ddg_clean
{
my $res = shift;
for my $k (keys %$res) {
delete $res->{$k} if $res->{$k} eq '';
if (ref $res->{$k} eq 'HASH') {
ddg_clean($res->{$k});
delete $res->{$k} unless keys %{$res->{$k}};
} elsif (ref $res->{$k} eq 'ARRAY') {
ddg_clean($_) for @{$res->{$k}};
delete $res->{$k} unless @{$res->{$k}};
}
}
}
sub ddg
{
my $q = shift;
my $h = new HTTP::Tiny;
my $res = $h->get(
'http://api.duckduckgo.com/?'
. $h->www_form_urlencode({ format => 'json', q => $q }));
die unless $res->{success};
ddg_clean($res = decode_json($res->{content}));
$res;
}
sub INDENT() { ' ' }
sub ddg_format
{
my ($it, $lev) = @_;
if (!ref $it) {
wrap(INDENT x $lev, INDENT x $lev, $it);
} elsif (ref $it eq 'HASH') {
join "\n", map {
my $val = ddg_format($it->{$_}, $lev+1);
if ($val =~ /\n/) {
INDENT x $lev . "$_:\n$val";
} else {
$val =~ s/^\s+//;
INDENT x $lev . "$_: $val";
}
} sort keys %$it;
} else {
join "\n", map { ddg_format($_, $lev+1) } @$it;
}
}
if (!defined caller) {
eval 'use Text::Wrap';
print ddg_format(ddg("@ARGV"), 0), "\n";
}