Usage
Usage¶
Six expressions, all taking a string column of URLs or bare hostnames:
https://www.bbc.co.uk/news | ||
|---|---|---|
tld.extract | {"www", "bbc", "co.uk", false} | struct: subdomain, domain, suffix, is_private |
tld.fqdn | www.bbc.co.uk | the whole hostname |
tld.registrable_domain | bbc.co.uk | what you register — domain.suffix |
tld.subdomain | www | |
tld.domain | bbc | the registrable label, tldextract's domain field |
tld.suffix | co.uk | the public suffix |
Nulls, and the one exception¶
The five single-value expressions return null for a part that does not exist. That matters in a DataFrame: an empty string is a value, so two rows that both failed to parse would compare equal and join to each other.
tld.extract is the exception, and deliberately so — it reproduces tldextract.ExtractResult verbatim, empty strings and all. Reach for it when porting existing tldextract code and you want the behavior unchanged; reach for anything else when the result is going into a join, a group-by, or a comparison.
fqdn vs. registrable_domain¶
The two differ on hosts that have no registrable domain. registrable_domain is strict — no recognized suffix means null, so an IP or a .local name drops out. fqdn just gives you the hostname:
tld.fqdn("url") # "127.0.0.1", "localhost", "printer.local"
tld.registrable_domain("url") # null, null, null
fqdn is also the normalized netloc — scheme, userinfo, port, path, query and fragment stripped, trailing root labels dropped, and the non-ASCII IDNA separators folded to . — so ftp://user:pw@ftp.gnu.org:2121/pub becomes ftp.gnu.org. Casing and punycode spelling are preserved, exactly like tldextract.
Expression namespace¶
Importing the package registers a .tld namespace:
df.with_columns(pl.col("url").tld.registrable_domain())
df.filter(pl.col("url").tld.suffix() == "org")
Scalars¶
For code that isn't holding a DataFrame — the same Rust core, no Polars round-trip:
tld.extract_scalar("https://www.bbc.co.uk/news")
# ('bbc.co.uk', 'bbc', 'co.uk') (registrable_domain, domain, suffix), nulls for absences
tld.extract_scalar_full("https://www.bbc.co.uk/news")
# ('www', 'bbc', 'co.uk', False) (subdomain, domain, suffix, is_private), tldextract-faithful
Private suffixes¶
The Public Suffix List has an ICANN section and a private section. Like tldextract, the private section is off by default:
tld.extract_scalar("pola-rs.github.io")
# ('github.io', 'github', 'io')
tld.extract_scalar("pola-rs.github.io", include_private=True)
# ('pola-rs.github.io', 'pola-rs', 'github.io')
Every expression takes the same include_private keyword.
Migrating from 0.1¶
parts() and top_domain() still work in 0.2 but emit a DeprecationWarning, and are removed in 0.3.
| 0.1 | 0.2 |
|---|---|
tld.parts(...).struct.field("full_domain") | tld.registrable_domain(...) |
tld.parts(...).struct.field("sld") | tld.domain(...) |
tld.parts(...).struct.field("tld") | tld.suffix(...) |
tld.top_domain(...) | tld.domain(...) |
Two things to watch when you migrate:
full_domainwas a misnomer. It held the registrable domain (bbc.co.uk). The actual full domain isfqdn()(www.bbc.co.uk), which is new in 0.2.top_domain()returned""where there was no registrable label;domain()returns null. If you were comparing against"", compare against null instead — or read the field offextract(), which keeps the empty-string form.