How to Extract The Domain From an URL with AppleScriptObjC?

Hey Folks,

Is there an AppleScriptObjC method for deconstructing an URL?

In particular at the moment I want the domain.

At the moment the cleanest method I know of is:

set theURL to "https://forum.latenightsw.com/"
set urlDomain to extractDomainFromURL(theURL)

on extractDomainFromURL(theURL)
   set theURL to theURL as URL
   set hostStr to DNS form of host of theURL
   set {oldTIDS, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "."}
   set urlDomain to (text items -2 thru -1 of hostStr) as text
   set AppleScript's text item delimiters to oldTIDS
   return urlDomain
end extractDomainFromURL

-Chris

I presume you mean top-level domain, and there’s no intrinsic way to know that. For example, you script fails with my domain, because it ends with .com.au. You have to do something like look up the public suffix list. See:
https://publicsuffix.org

Zoiks! That’s gnarly…  :sunglasses:

Thanks.

@ccstone, this is a method I devised last year, if it’s of any help at all:

on domain for |url| as {record, text}
        set text item delimiters to "."
        set subdomains to the text items of (hostname for |url|)
        repeat while the hostnameDoesResolve(rest of subdomains)
                set subdomains to the rest of the subdomains
        end repeat
        return the subdomains as text
end domain

on hostname for |url| as {record, text}
        tell the |url| as {URL, record} to  ¬
                return the host's DNS form
end hostname

on hostnameDoesResolve(hostname as text)
        tell ("mailto:" & hostname) as URL to tell ¬
                host & {dotted decimal form:false} ¬
                to get dotted decimal form ≠ false
end hostnameDoesResolve

I don’t have a Mac to do some tests on the above set of routines, since they’ve been sitting in the recesses of my iCloud drive for some time. But, all being well, then calling this:

domain for "https://images.google.co.uk/"

ought to return:

"google.co.uk"
2 Likes

Hey @CJK,

That’s spiffy.

Well done!

-Chris

1 Like

Here is my version, maybe not better but different :slight_smile:

use framework "Foundation"
use scripting additions

set theHost to (current application's |NSURL|'s URLWithString:"https://images.google.co.uk/")'s |host|()
set theItems to (theHost's componentsSeparatedByString:".") as list
set theDomain to items 2 thru -1 of theItems
set ASTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "."
set theDomain to theDomain as text
set AppleScript's text item delimiters to ASTID
return theDomain

Or

use framework "Foundation"

set theURL to "https://images.google.co.uk/"
log (current application's NSURLComponents's componentsWithString:theURL)'s |description|() as text
set components to (current application's NSURLComponents's componentsWithString:theURL)
set theItems to ((components's valueForKey:"host")'s componentsSeparatedByString:".") as list
set theDomain to text -3 thru -1 of theItems
set ASTID to AppleScript's text item delimiters
set AppleScript's text item delimiters to "."
set theDomain to theDomain as text
set AppleScript's text item delimiters to ASTID
return theDomain

What would this return for the URLs below ?

https://google.com
https://google.co.uk
http://127.0.0.1
http://localhost

The example of your URL you only need the key host

ex.

use framework "Foundation"

set theURL to "https://localhost"
log (current application's NSURLComponents's componentsWithString:theURL)'s |description|() as text
set components to (current application's NSURLComponents's componentsWithString:theURL)
set theItems to (components's valueForKey:"host") as text

That wasn’t what I asked. Did you run any of those URLs through your suggested scripts above ?

Yes, by eyeballing the URL, it’s easy to see that the host name is the domain name in each of those cases. But a script cannot eyeball a URL like a human. And what if the URL wasn’t a familiar one ?

I get your point and I agree with you in that regard… it fails