The problem is that what can be considered a URL actually varies depending on context. And sometimes something that is not a complete URL can be promoted to one.
I suggest you look up Interpreter["URL"]
and its restrictions. Then you'll probably be able to write something like:
URLQ[s_] := !FailureQ[Interpreter["URL"][s]]