Update:
here's the same, but better and in a package on GitHub now:
Get["https://raw.githubusercontent.com/b3m2a1/mathematica-tools/master/DynamicWebImage.wl"]
i = Last[animals];
DynamicWebImageBrowser[Dynamic[i], animals]

Here's a way to do this for free with the Qwant API:
dynamicWebImage[
imgVar_Dynamic,
caching : True | False : True,
ops : OptionsPattern[Join[Options@DynamicModule, Options@Image]]
] :=
DynamicModule[
{img},
Replace[
imgVar, {
Verbatim[Dynamic][var_, o___?OptionQ] :>
Dynamic[
img =
Image[
dynamicWebImage`Private`qwantSingleSearch[var, caching]["Image"],
FilterRules[{ops},
Options@Image
]
],
o],
Verbatim[Dynamic][var_, f : Except[_?OptionQ], o___?OptionQ] :>
Dynamic[
img =
Image[
Last@Through[
Flatten[List@f][
dynamicWebImage`Private`qwantSingleSearch[var, caching]]
],
FilterRules[{ops},
Options@Image
]
],
o
]
}],
Initialization :>
{
OptionValue[Initialization],
If[! AssociationQ@dynamicWebImage`Private`$qwantCache,
dynamicWebImage`Private`$qwantCache = <||>
],
dynamicWebImage`Private`qwantSingleSearch[
q_String?(StringLength[StringTrim[#]] > 0 &),
cached : True | False : True] :=
Replace[
dynamicWebImage`Private`$qwantCache[q],
Except[_Association?(KeyMemberQ["Image"])]:>
With[{
r =
First@Normal@
dynamicWebImage`Private`qwantInstance["ImageSearch",
"q" -> q, "count" -> "1"]
},
If[cached, dynamicWebImage`Private`$qwantCache[q] = r, r]
]
],
dynamicWebImage`Private`qwantSingleSearch[__] :=
None,
If[! TrueQ[dynamicWebImage`Private`qwantPacletUpdated],
If[Length@PacletManager`PacletFind["ServiceConnection_Qwant"] > 0,
PacletInstall,
PacletUpdate
][
"ServiceConnection_Qwant",
"Site" ->
"https://www.wolframcloud.com/objects/b3m2a1.paclets/\
PacletServer"
];
dynamicWebImage`Private`qwantPacletUpdated =
Length@PacletManager`PacletFind["ServiceConnection_Qwant"] > 0
],
dynamicWebImage`Private`qwantInstance = ServiceConnect["Qwant"]
},
Evaluate[
Sequence @@ FilterRules[{
ops
},
Options@DynamicModule
]
],
SynchronousInitialization->True
]
This just sets up a little framework to work with this answer.
Here's a fun example of what you can do with it:
animals =
Cases[
Import[
"https://www.livescience.com/13524-500-cutest-animals-list.html",
{"HTML", "XMLObject"}
],
XMLElement["p", _,
{a_String?(StringStartsQ[Whitespace ~~ DigitCharacter .. ~~ "."])}
] :>
StringTrim@
First@StringSplit[Last@StringSplit[a, ". "], "(" | " aka "],
\[Infinity]];
a = Last@animals;
Framed[
Column[{
Panel[
InputField[Dynamic[a],
String,
MenuList -> animals
],
ImageSize -> 350,
Appearance ->
Lookup[
FrontEndResource["FEExpressions",
"MoreLeftSetterNinePatchAppearance"],
"Hover"
],
Alignment -> Center
],
dynamicWebImage[
Dynamic[a],
ImageSize -> 350,
DynamicEvaluationTimeout -> Infinity
]
},
Spacings -> 0
],
FrameMargins -> None,
FrameStyle -> GrayLevel[.85]
]

Note that that's really just so much formatting around:
dynamicWebImage[
Dynamic[a],
ImageSize -> 350,
DynamicEvaluationTimeout -> Infinity
]