Google Autocomplete Fun

16

3

Your task is to create a program which, given an input string, will output the first Google autocomplete result for that search. The format of input/output is up to you.

Rules

  1. Your program must take 1 input, a string, and output the top Google autocomplete/auto-fill suggestions result. The format of input/output is up to you. Just be sure to mention what your I/O format is.
  2. Obviously, accessing the Internet is allowed.
  3. URL shorteners (like bit.ly, TinyURL, etc.) are strictly disallowed. You should fetch your autocomplete results from this URL: http://suggestqueries.google.com/complete/search?client=your_browser&q=your_query or http://google.com/complete/search?client=your_browser&q=your_query. You are allowed to assume any browser name (or string, for that matter) for client. In the program I wrote, I assume Chrome. Any browser name or string should work. You are allowed to pass any options to the webpage as long as you are using some variant of http://suggestqueries.google.com/complete/search.
  4. Please provide an explanation of how your program works. It is not mandatory, but I strongly advise it.
  5. All standard loopholes are strictly forbidden.

Test Cases

These are constantly changing, so edit this post if these become out-of-date.

'how to'
  => 'how to make slime'
'code golf'
  => 'code golf languages'
'you'
  => 'youtube'
'g'
  => 'google' (why would you google 'google'?)

This is , so may the shortest code win and the best programmer prosper...

ckjbgames

Posted 2017-04-23T21:09:32.770

Reputation: 1 287

3I would standardise a client name, to make it fair – Beta Decay – 2017-04-23T21:16:11.353

7Why the strict URL? As long as suggestqueries.google.com is used, without any URL shorteners, I don't see any problems. – Dennis – 2017-04-23T21:30:23.990

In particular, if we can use output=toolbar, we don't have to specify a client at all. – Dennis – 2017-04-23T21:36:10.893

I don't think the strict url should be enforced. Banning URL shorteners should do the trick already. – Bald Bantha – 2017-04-23T21:40:09.860

Somewhat related (both involve parsing downloaded JSON objects) – Beta Decay – 2017-04-23T21:44:04.707

Nevermind, output=toolbar generates XML, the OP's URL doesn't. – Dennis – 2017-04-23T22:03:18.637

@Dennis I did that because it was suggested that I have a standard URL for everyone to use (by @Riker). – ckjbgames – 2017-04-23T23:20:51.883

Well, I don't think it's a good idea. If a language can handle XML easier, why not let it use output=toolbar instead? There are other output methods that might also be interesting. – Dennis – 2017-04-23T23:29:09.057

@Dennis Ok. I will change it where people will only have to use any URL from suggestqueries.google.com/complete/search. – ckjbgames – 2017-04-23T23:44:09.287

@Dennis Done! Now only requires that the URL http://suggestqueries.google.com/complete/search be used.

– ckjbgames – 2017-04-23T23:49:21.760

@ckjbgames Why use suggestqueries? https://www.google.com/complete is working fine for me, too. – mınxomaτ – 2017-04-24T00:14:56.767

@mınxomaτ It gives me a 404 Error when I try, but I'm glad it works for you. – ckjbgames – 2017-04-24T00:20:30.700

@ckjbgames Example: https://www.google.com/complete/search?client=hp&q=a. I'm just saying requiring that subdomain is not required. – mınxomaτ – 2017-04-24T00:21:23.673

@mınxomaτ Oh. It does work. Cool! – ckjbgames – 2017-04-24T00:23:16.777

2@mınxomaτ but why not https -> http (save 1 byte), remove www. (save 4 bytes), google.com -> google.us (save 1 byte) or even google.com -> g.cn (save 6 bytes; i'm not sure why this still works, but it seems that it still working in 20170424) – tsh – 2017-04-24T01:23:31.570

3Aren't search suggestions different for different users and regions? I don't think having standard test cases really works for this. – MrZander – 2017-04-24T15:53:10.140

Answers

8

Zsh + coreutils + w3m, 88 71 68 bytes

echo `w3m "google.com/complete/search?client=gma&q=$*"|cut -d\" -f4`

Switching from Bash to Zsh saved 3 bytes.

Thanks to @FatalMerlin for the shorter URL, saving 17 bytes!

Sample run

$ zsh complete.sh how to
how to make slime
$ zsh complete.sh dont you
don't you forget about me
$ zsh complete.sh don\'t you
don't you worry child

Dennis

Posted 2017-04-23T21:09:32.770

Reputation: 196 637

3Of all things, why is "make slime" the first suggestion? Just how many people are out there making slime as we speak? – MildlyMilquetoast – 2017-04-23T23:55:57.843

27No clue. It was how to raise your i.q. by eating gifted children for a while, so I'd consider this an improvement. – Dennis – 2017-04-23T23:57:26.850

Dang, I do love w3m. It lets me browse without distractions and it's just pretty cool altogether. – ckjbgames – 2017-04-24T00:21:28.113

1@MistahFiggins Blame Minecraft for that one. – JakeSteam – 2017-04-24T11:27:10.437

@MistahFiggins Maybe they all just want to make(1) slime.

– Arminius – 2017-04-24T15:17:08.947

@Dennis It's a book

– Draco18s no longer trusts SE – 2017-04-26T03:14:57.767

You stand victorious. – ckjbgames – 2017-06-29T17:03:34.763

12

Vim 8 + unimpaired.vim, 93 89 85 70 73 71 bytes

  • -4 bytes thanks to tsh
  • -2 bytes thanks to Ian Emnace
  • -2 bytes thanks to FatalMerlin
  • -1 byte thanks to tsh/ckjbgames
:s/ /+/g
D:e http://google.us/complete/search?client=gma&q="
d3f";D]yy

As a bonus, the last bytes look like they're winking at you ;D Since this contains non-printing characters, the explanation contains substitutions (and I've replaced the pre-querystring part of the url with [url], for brevity):

:s/ /+/g<CR>D:e [url]?client=gma&q=<C-R>"<CR>d3f";D]yy
:s/ /+/g<CR>                                           " Replace spaces with +
            D                                          " Delete and yank result
             :e                                        " Type :e ('edit' command) and a space
                [url]?client=gma&q=                    " Type the url, except the query
                                   <C-R>"              " Paste from the default register
                                         <CR>          " Execute the command, which opens the response
                                                       "   in a new buffer
                                             d3f"      " Delete through the first three quotation marks
                                                       "   This deletes everything before the suggestion
                                                 ;     " Repeat motion; this jumps to the next \"
                                                  D    " Delete everything from there, leaving only the suggestion
                                                   ]yy " unimpaired.vim C string unescape to handle escaped '

As far as running goes, it works fine if you save it to a file named script and run with vim -s script input.txt on macOS, at least. It doesn't work if you add -u NONE, but it works fine if my .vimrc is empty. I assume it is using something from the system .vimrc to make the URL stuff work. This means, however, that it doesn't work in V, so no TIO link.

Some more test cases:

'what' => 'whataburger'
'what ' => 'what time is it' (Seriously? People Google that?)

What I really need is a way to open a URL with spaces in it. Replacing them with + first is just too many bytes!

Brian McCutchon

Posted 2017-04-23T21:09:32.770

Reputation: 503

1should space be replaced by plus sign+? – tsh – 2017-04-24T01:59:37.940

1@tsh You're right! Now somebody tell me how I can save 2 bytes and beat Dennis :) – Brian McCutchon – 2017-04-24T02:04:52.797

for netrw to work you need filetype plugin on – tbodt – 2017-04-24T02:19:28.263

which is set by default in vim 8 so I guess you can say that's your language – tbodt – 2017-04-24T02:19:43.187

@tbodt So why is it not set when I use -u NONE, I wonder? – Brian McCutchon – 2017-04-24T02:22:36.303

oh it's because -u NONE disables plugins whereas -u NORC just disables vimrc – tbodt – 2017-04-24T02:57:44.933

@tbodt On my machine, at least, it still fails with -u NORC. I checked the system vimrc and don't see any filetype commands. In fact, it even fails with touch tmp.vim; vi -u tmp.vim -s script tmp.txt. – Brian McCutchon – 2017-04-24T03:01:17.423

1You can paste the " register (default) in insert/command mode by doing <C-r>". You can shave off a few bytes by doing :r [url]?client=opera&q=^R" instead of q:ir [url]?client=opera&q=<esc>p. ^R is the actual byte sent when you press <C-r>, not the keys ^ and R together, so it only counts as one byte. – Ian Emnace – 2017-04-24T08:55:57.573

1

When I count the bytes I get 88. Also you can save bytes by changing the URL to http://google.com/complete/search?client=hp&q=your_query (client=gma => Plain JSON and shorter text.).

– FatalMerlin – 2017-04-24T13:53:37.593

@FatalMerlin I think that's because the escape character was lost in translation. – Brian McCutchon – 2017-04-24T15:05:21.840

@FatalMerlin But you're right about gma. hp gives me some annoying unicode-escaped html tags in the output that I can't get rid of without wasting bytes. – Brian McCutchon – 2017-04-24T15:09:19.837

@BrianMcCutchon ah okay, I forgot about those :) But than I'm glad that at least one thing is useful! – FatalMerlin – 2017-04-24T15:14:22.497

@IanEmnace Thank you! I forgot you could do that in command mode. – Brian McCutchon – 2017-04-24T15:25:06.210

You need to save 3 bytes if you want to outgolf him again. – ckjbgames – 2017-04-26T00:44:13.010

@ckjbgames The substitution is too verbose and I can't get rid of the protocol. Plus, I think I need to add a few bytes to handle hyphens correctly (]yy with the tpope/unimpaired plugin). – Brian McCutchon – 2017-04-26T03:27:50.427

@BrianMcCutchon Yeah. Dennis will outgolf you in the end, though. – ckjbgames – 2017-04-26T16:51:27.363

Check out the comments on this post: You could shorten the URL to http://g.cn/complete/search?client=gma&q=. – ckjbgames – 2017-05-15T13:15:56.233

@ckjbgames I get some HTML containing 301 Moved. That said, google.us works. – Brian McCutchon – 2017-05-27T19:10:26.703

@BrianMcCutchon Cool. For me, it redirects to google.cn. – ckjbgames – 2017-05-29T22:38:15.267

7

Python + requests 121 117 103 bytes

from requests import*
lambda s:get("http://google.com/complete/search?client=gma&q="+s).json()[1][0][0]

ovs

Posted 2017-04-23T21:09:32.770

Reputation: 21 408

5

JavaScript, 109 Bytes

q=>fetch("//suggestqueries.google.com/complete/search?client=chrome&q="+q).then(r=>r.json()).then(r=>r[1][0])

Promise, you gotta love it, but man is it verbose! This answer uses fetch(), a promise-based fetch API present in modern browsers. Promises work by establishing handlers for async actions at the beginning, like callbacks, but better. The .then() takes a function which will be called with the result of the async action. .then(r=>r.json()) uses the .json() response method to convert the text array to a manipulable variable, the second .then() just pulls the first response.

Usage:

S = q=>fetch("//suggestqueries.google.com/complete/search?client=chrome&q="+q).then(r=>r.json()).then(r=>r[1][0])

S("node.js").then(console.log); // Prints the result to the debug console

MayorMonty

Posted 2017-04-23T21:09:32.770

Reputation: 778

2.then(r=>r.json()).then(r=>r[1][0]) -> .then(r=>r.json()[1][0]) Enjoy 11 characters less ;-) – Stephan Bijzitter – 2017-04-24T13:23:34.133

I've tried in Firefox 52 and Chrome 57, on this page, Google's homepage, and about:blank, and I just keep getting CORS errors. Have you gotten it to work successfully? – ETHproductions – 2017-04-24T15:35:42.080

@ETHproductions Yes, there are CORS problems, you must execute on the domain https://suggestqueries.google.com

– MayorMonty – 2017-04-24T19:32:08.727

@StephanBijzitter .json() returns a Promise, it's async, for some reason

– MayorMonty – 2017-04-24T19:33:20.660

Indeed it works there, thanks! – ETHproductions – 2017-04-24T19:36:55.733

Oh, you're completely right! I never even noticed ;O – Stephan Bijzitter – 2017-04-24T20:41:02.663

Promise's verbosity isn't the problem, it's fetch. I'd really love to know why .json() is async. – Steve Bennett – 2017-04-26T06:01:55.403

OIC. Because fetch() returns before the body has necessarily even been fully received. – Steve Bennett – 2017-04-26T06:03:08.463

1

PowerShell, 133 115 bytes

([net.webclient]::new().downloadstring("http://google.com/complete/search?client=gma&q=$_")|convertfrom-json)[1][0]

Sample run

Windows CMD command line:

powershell.exe -c "'code golf l'|%{([net.webclient]::new().downloadstring(""""http://google.com/complete/search?client=gma&q=$_"""")|convertfrom-json)[1][0]}"

PowerShell console:

'code golf l'|%{([net.webclient]::new().downloadstring("http://google.com/complete/search?client=gma&q=$_")|convertfrom-json)[1][0]}

Andrei Odegov

Posted 2017-04-23T21:09:32.770

Reputation: 939

1

C#, 192 112 111 Bytes

Saved 80 Bytes thanks to @TheLethalCoder. Thanks for reformatting my code, I didn't know it was allowed to just leave off the surrounding Class and Method Body :)

Saved another Byte by replacing gma by hp, as it doesn't matter for the parsing and there is just some gibberish before the response body.

I litterally brute-forced the API to find gma and hp.

s=>new System.Net.WebClient().DownloadString("http://google.com/complete/search?client=hp&q="+s).Split('"')[3];

FatalMerlin

Posted 2017-04-23T21:09:32.770

Reputation: 113

1

Groovy, 122 bytes

{Eval.me(new URL("http://suggestqueries.google.com/complete/search?client=chrome&q="+it).text.split(",\\{")[0]+"]")[1][0]}

Basically:

  1. Get the text from the end-point.

  2. Remove the part with the brackets at the end, this isn't valid syntax.

  3. Parse the remaining bit as a groovy array.

  4. Grab the second element of the result array.

enter image description here

Magic Octopus Urn

Posted 2017-04-23T21:09:32.770

Reputation: 19 422

1

R, 111 bytes

Long time since I last came here but giving it a shot:

jsonlite::fromJSON(readLines(url(paste0("http://google.com/complete/search?client=gma&q=",scan(,"")))))[[2]][1]

Using the package jsonlite to convert the string fetched from readLines() into a list object.

Subsequently extract the second element, e.g (gives a warning that we don't have to care about):

> jsonlite::fromJSON(readLines(url(paste0("http://google.com/complete/search?client=gma&q=",scan(,"")))))[[2]][1]
1: "how to"
2: 
    Read 1 item
[[1]]
[1] "how to make slime"

Warning message:
    In readLines(url(paste0("http://google.com/complete/search?client=gma&q=",  :
                                incomplete final line found on 'http://google.com/complete/search?client=gma&q=how to'

Billywob

Posted 2017-04-23T21:09:32.770

Reputation: 3 363

0

C#, 127 bytes

s=>new System.Net.WebClient().DownloadString("http://suggestqueries.google.com/complete/search?client=gma&q="+s).Split('"')[3];

Complete and formatted version:

static void Main()
{
    System.Func<string, string> f = s =>
        new System.Net.WebClient()
                      .DownloadString("http://suggestqueries.google.com/complete/search?client=gma&q="+s)
                      .Split('"')[3];

    System.Console.WriteLine(f("you"));
    System.Console.ReadLine();
}

TheLethalCoder

Posted 2017-04-23T21:09:32.770

Reputation: 6 930

Thanks for the hint about leaving of the Method and Class Body! – FatalMerlin – 2017-04-24T15:03:17.737