Need a way to extract a domain name without the subdomain from a url using Python urlparse.
For example, I would like to extract "google.com"
from a full url like "http://www.google.com"
.
The closest I can seem to come with urlparse
is the netloc
attribute, but that includes the subdomain, which in this example would be www.google.com
.
I know that it is possible to write some custom string manipulation to turn www.google.com into google.com, but I want to avoid by-hand string transforms or regex in this task. (The reason for this is that I am not familiar enough with url formation rules to feel confident that I could consider every edge case required in writing a custom parsing function.)
Or, if urlparse
can't do what I need, does anyone know any other Python url-parsing libraries that would?
Input: http://www.google.com
Result: google.com
This is not a standard decomposition of the URLs.
You cannot rely on the
www.
to be present or optional. In a lot of cases it will not.So if you do want to assume that only the last two components are relevant (which also won't work for the uk, e.g.
www.google.co.uk
) then you can do asplit('.')[-2:]
.Or, which is actually less error prone, strip a
www.
prefix.But in either way you cannot assume that the
www.
is optional, because it will NOT work every time!Here is a list of common suffixes for domains. You can try to keep the suffix + one component.
https://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1
But how do you plan to handle for example
first.last.name
domains? Assume that all the users with the same last name are the same company? Initially, you would only be able to get third-level domains there. By now, you apparently can get second level, too. So for.name
there is no general rule.There are multiple Python modules which encapsulate the (once Mozilla) Public Suffix List in a library, several of which don't require the input to be a URL. Even though the question asks about URL normalization specifically, my requirement was to handle just domain names, and so I'm offering a tangential answer for that.
The relative merits of publicsuffix2 over publicsuffixlist or publicsuffix are unclear, but they all seem to offer the basic functionality.
publicsuffix2:
publicsuffix
.publicsuffixlist:
idna
support, which I however have not tested.publicsuffix:
You probably want to check out tldextract, a library designed to do this kind of thing.
It uses the Public Suffix List to try and get a decent split based on known gTLDs, but do note that this is just a brute-force list, nothing special, so it can get out of date (although hopefully it's curated so as not to).
So in your case:
Using the tldexport works fine, but apparently has a problem while parsing the blogspot.com subdomain and create a mess. If you would like to go ahead with that library, make sure to implement an if condition or something to prevent returning an empty string in the subdomain.
This is an update, based on the bounty request for an updated answer
Start by using the tld package. A description of the package:
This outputs
Notice that it correctly handles country level TLDs by leaving
co.uk
andco.it
, but properly removes thewww
andmail
subdomains for both.com
and.co.uk
The
update_tld_names()
call at the beginning of the script is used to update/sync the tld names with the most recent version from Mozilla.