Fabulous glamour shot

11

2

enter image description here

Found this picture on the web today. Being a lazy programmer, I don't want to actually open google and type a couple of characters. Way too much work! This is such an important task that it should be automated.

Challenge

Everyone knows that the first image in a google search result is always the best. Hence it should be presented to the user.

You are to write a program or function which takes a string as parameter and displays the first image it finds on google when you search for that name + the words glamour shot behind it.

Google search queries

To search for images on google, the url should contain the query parameter tbm=isch and q=query, with query being the name you want to search for.
A valid query string for my name Bas would be www.google.com/search?tbm=isch&q=Bas

Input

Your program or function takes a single parameter of input, which is the name you want to search for on google. This string will consist of the characters [a-z], [A-Z], [0-9] and (space). This string can be space seperated, to search for a space seperated string on google, one should replace the spaces with +. For example, this is a valid query:
www.google.com/search?tbm=isch&q=Bassdrop+Cumberwubwubwub+glamour+shot

Output

The image can either be drawn to the screen, or saved to a file (in any format).
If the first search result on google is a gif file, you can either show the gif or show any frame of that gif.

Test cases

Run this snippet to see the expected results

<pre>f('Bas') // www.google.com/search?tbm=isch&q=Bas+glamour+shot

<img src="http://i.stack.imgur.com/IViaM.jpg" style="width:40%;height:40%"/>

<pre>f('Bassdrop Cumberwubwubwub') // www.google.com/search?tbm=isch&q=Bassdrop+Cumberwubwubwub+glamour+shot

<img src="http://i.stack.imgur.com/tdhvW.png" style="width:40%;height:40%"/>

This is , shortest code in bytes wins!

Bassdrop Cumberwubwubwub

Posted 2016-10-04T09:55:14.990

Reputation: 5 707

What characters need to be supported in the input? Do we need to worry about URL encoding? – Martin Ender – 2016-10-04T10:09:44.283

@Martin Ender [a-z0-9], edited my post. The urls will look like the examples I provided, no encoding needed, just space to + – Bassdrop Cumberwubwubwub – 2016-10-04T10:13:09.797

I guess, A-Z can also appear, judging by your example? – Martin Ender – 2016-10-04T10:55:12.637

@MartinEnder Yes, it's case insensitive. Forgot to mention – Bassdrop Cumberwubwubwub – 2016-10-04T10:56:02.613

@BassdropCumberwubwubwub woops rookie mistake, I had indeed forgotten to escape the ampersand – Aaron – 2016-10-07T13:25:47.637

2There's a surprising number of people posing with guns when you play this game :D – Beta Decay – 2017-05-26T06:23:40.347

What exactly counts as being drawn to the screen? Would navigating to the source location in IE or Chrome count as being drawn to the screen? – Taylor Scott – 2017-05-30T17:41:46.973

Can I get the thumbnail of the image rather than the image itself? – BlackCap – 2017-05-30T21:59:14.137

it is good you included the search queries restricts, otherwise one could just set up a custom short-url website which takes care of it. – phil294 – 2017-06-03T04:13:09.957

Answers

8

PowerShell v4+, 160 bytes

param($a)iwr (((iwr "google.com/search?tbm=isch&q=$($a-replace' ','+')+glamour+shot").links|?{$_.innerhtml-like"*$a*"})[0].innerhtml-split'"')[3] -outf "$a.jpg"

Takes input $a as a string. Does an Invoke-WebRequest (iwr) to the appropriate Google location, using inner-string script block to -replace spaces with + in the input string. We take the .links of that, where the .innerhtml is -like our input string. That yields the links with the proper thumbnail description. Take the first [0] one of those, take its .innerhtml and -split it on quotations. The fourth [3] element is the text inside the img src=" portion, so we do another iwr on that, specifying -outfile to be $a.jpg in the local folder. Since these are just the Google generated thumbnails, they're guaranteed to be jpg.

AdmBorkBork

Posted 2016-10-04T09:55:14.990

Reputation: 41 581

1you can change out google.com with google.nl for -1 byte – Taylor Scott – 2017-05-26T19:27:13.753

4

Excel VBA +, 465 332 Bytes

NOTE: Uses References to

  • Microsoft HTML Object Library
  • Microsoft Internet Controls
  • Microsoft Scripting Runtime

Golfed:

Full Sub routine that takes input n (short for name) of expected type Variant/String and outputs the first google image search result for the query of that name and glamour shot to an internet explorer window.

Sub g(n)
Set i=New InternetExplorer
l="google.nl/search?tbm=isch&q="&Replace(n," ","+")&"+glamour+shot"
For y=0To 2
i.navigate l
While i.readyState<4
DoEvents
Wend
j=0
Do Until InStr(1,l,IIf(y,"yp","res"))
j=j+1
Set x=i.document.getElementsByTagName(IIf(y,"img","a"))(j)
If y Then l=x.src Else l=x.href
Loop
Next
i.visible=1
End Sub

-2 bytes for removing white space in If InStr(1, a.href, "imgres") Then

-2 bytes for changing .navigate (a.href) to .navigate a.href

-27 bytes for reducing for each a in ... if (...) then ... end if .. next loop to do until ... loop

-10 bytes for condensing imgres to res and encrypted to yp

-8 bytes for removing initalizers for j, k and assuming clean module

-1 byte for changing google.com to google.nl

-3 bytes for replacing Dim i as New ... with Set i=New ...

-8 bytes for removing SHDocVw. class reference

-12 bytes for removing with i block

-7 bytes for removing i.quit - this causes some memory leakage by leaving internet explorer open in the background, as such it is recommended that either the full ungolfed version is used instead or that the internet explorer task is terminated through task manager after use

-6 bytes for moving i.navigate into helper subroutine h

-13 bytes for moving Do Until ... Loop into helper subroutine

-2 bytes by moving j=0 into helper and removing ,j, ,0 (x2)

-11 bytes for converting to an anonymous immediate window function

-8 bytes for reducing helper function calls into for .. next loop

-16 bytes for changing output from Sheets(1) picture object to displaying via the InternetExplorer object

Ungolfed, 1304 Bytes

Option Private Module
Option Compare Text
Option Explicit
Option Base 0

Sub GlamourShot(ByVal name As String)

    Dim ie As New SHDocVw.InternetExplorer, _
        doc As MSHTML.HTMLDocument, _
        link As String, _
        j As Integer, _
        k As Integer

    With ie
        On Error GoTo CloseIE #'prevents memory leak

        Let .visible = True
        Call .navigate("www.google.com/search?tbm=isch&q=" & _
                    Replace(name, " ", "+") & _
                    "+glamour+shot")
        While .readyState <> READYSTATE_COMPLETE Or .Busy
            VBA.DoEvents
        Wend

        Set doc = .document

        Let j = 1
        Do Until InStr(1, link, "imgres") > 0
            Let link = doc.getElementsByTagName("a")(j).href
            Let j = j + 1
        Loop

        Call .navigate(link)
        While .readyState <> READYSTATE_COMPLETE Or .Busy
            VBA.DoEvents
        Wend

        Let k = 1
        Do Until InStr(1, link, "encrypted") > 0
            Let link = doc.getElementsByTagName("img")(k).src
            Let k = k + 1
        Loop

        With ThisWorkbook.ActiveSheet
            Call .Range("A1").Select
            Call .Pictures.Insert(link)
            Call .Activate
        End With
CloseIE:
        Call .Quit
    End With
End Sub

Usage gif

Usage Gif

Taylor Scott

Posted 2016-10-04T09:55:14.990

Reputation: 6 709

3

Vimperator, 30 keystrokes

pgi<End> glamour shot<CR>fi222jf<CR>fim2

Alternatively 27 keystrokes if you don't need the highest resolution image:

pgi<End> glamour shot<CR>fi222j;I<CR>

Video: https://youtu.be/t8824UjlYt8



Fortunately the standard search engine in Firefox is google, and Vimperator let you type hints by default. This is longer than it has to be to make sure that it always works regardless of what you search for.

Takes input through the clipboard.

Explanation:

p             Google the contents of the clipboard
gi            Select the search box
<End>         Move the cursor to the end of the text
 glamour shot Type " glamour shot"
<CR>          Press enter to search
fi2           Click the second link that begins with the letter "i" (images)
22j           Go 22 scroll steps down on the page.
              This makes it so that the first row of images are at
              the very top of the screen.

f<CR>         Click the first clickable element, which is the
              first image because we scrolled down

fim2          Click the second link containing "im" (view image)

Thanks to @TaylorScott for finding an edge case.

BlackCap

Posted 2016-10-04T09:55:14.990

Reputation: 3 576

Does this handle cases when google recommends other search results as is the cases such as this

– Taylor Scott – 2017-05-30T21:10:23.630

@TaylorScott It does not, but I am unable to get recommendations in Firefox. Could it be browser dependent? – BlackCap – 2017-05-30T21:18:16.597

1Nevermind, I got them for a different search – BlackCap – 2017-05-30T21:21:45.803

3

Python 3.6, 247 242 232 maybe 224 bytes

This is a cute attempt to solve this one. It will save a the file as p.png in the current directory.

import sys; import requests as r; from bs4 import BeautifulSoup as s;
n = sys.argv[1]; open('p.png', 'wb').write(r.get(s(r.get(f'https://www.google.com.br/search?tbm=isch&q={n}+glamour+shot').content,'lxml').find_all('img')[1].get('src')).content)

To run it with ease from the command line, just place the above content in a file, such as glamour.py and run:

$ python glamour.py NAME_YOU_WANT

Update 1: Better version with new google url

import sys; import requests as r; from bs4 import BeautifulSoup as s;
n = sys.argv[1]; open('p.png', 'wb').write(r.get(s(r.get(f'http://www.google.nl/search?tbm=isch&q={n}+glamour+shot').content,'lxml').find_all('img')[1].get('src')).content)

Update 2:

I saved a few bytes:

  • By only importing the get function from the requests module
  • taking advantage of the new python 3.6 string interpolation f flag without allocating the sys.argv to a variable
  • eliminating some white spaces
  • turning it into a one-liner
  • removing the parser specification from the BeautifulSoup call

The last one is controversial, since it results in a std.output message telling the programmer to specify the parser for cross platform compatibility, so it might be considered unwanted output.

Here is the 224 bytes version:

import sys;from requests import get;from bs4 import BeautifulSoup as s;open('p.png','wb').write(get(s(get(f'http://www.google.nl/search?tbm=isch&q={sys.argv[1]}+glamour+shot').content).find_all('img')[1].get('src')).content)

Here is the 232 bytes version:

import sys;from requests import get;from bs4 import BeautifulSoup as s;open('p.png','wb').write(get(s(get(f'http://www.google.nl/search?tbm=isch&q={sys.argv[1]}+glamour+shot').content, 'lxml').find_all('img')[1].get('src')).content)

But the shorter version could be used if std.out is redirected to /dev/null or something :D

Gui42

Posted 2016-10-04T09:55:14.990

Reputation: 130

I could probably have a version with urllib + html.parse so that it can run entirely with the standard library. – Gui42 – 2017-05-31T19:40:37.113

1you can likely use www.google.nl/ or maybe even google.nl instead of https://www.google.com.br/ to save some bytes – Taylor Scott – 2017-05-31T19:42:35.497

1for some reason, I have to keep http:// for it to work with requests. But the Brazilian google gave me funnier results, so I loose on fun points :D – Gui42 – 2017-05-31T19:48:41.997

Does this handle cases when google recommends other search results as is the cases such as this (you may have to do multiple searches to get suggestions like this to pop up)

– Taylor Scott – 2017-05-31T19:51:09.003

I also love how I gain a few bytes thanks to the n = 'something'; f'{n}_here' instead of n = 'something'; '{n}_here'.format(n = n) or n = 'something'; '{}_here'.format(n) – Gui42 – 2017-05-31T19:51:13.227

@TaylorScott, i don't know. When I inspected the url for the first time, it had those headers, but I am not sure how they were introduced in the HTML response. Also the first element of the BeautifulSoup iterable where I retrieved all img tags was usually only garbage, so those headers might be there. – Gui42 – 2017-05-31T19:56:38.153

@Gui42The best way that I had to ensure that this handled the suggestions was to ensure that the link (src) for the final image contained encrypted (shortened for searching to yp based off of the possible domains) – Taylor Scott – 2017-05-31T20:49:09.553

Let us continue this discussion in chat.

– Taylor Scott – 2017-05-31T20:50:14.640

1

Racket, 284 byes

(require net/url html-parsing sxml racket/draw)(define(g n)(let([g(compose get-pure-port string->url string-append)])(make-object bitmap%(g(car((sxpath"//*[@id='ires']//@src/text()")(html->xexp(g"http://www.google.com/search?tbm=isch&q="(string-replace n" ""+")"+glamour+shot"))))))))

Screenshot: enter image description here

Geoff Reedy

Posted 2016-10-04T09:55:14.990

Reputation: 2 828