我提出了自己的解决方案,主要基于 R 包 tldextract,它依赖于 Public Suffix List。我详细解释解决方案here。这假设您已将公共后缀列表作为 domains_tld 导入 Presto,其中包含一个名为 tld 的列包含 TLD。
首先是一些玩具数据:
CREATE TABLE dat AS
SELECT url, url_extract_host(url) AS url_host FROM
(WITH temp AS (
SELECT * FROM (VALUES
('https://subsub.sub.example.co.uk/page?q=1234#abcd'),
('https://example.api.gov.uk/page?q=1234#abcd'),
('https://example.co.uk/page?q=1234#abcd'),
('https://www.example.com/page?q=1234#abcd'),
('https://example.com/page?q=1234#abcd')) AS tab (url))
SELECT url from temp)
接下来,连接生成的部分,从最后一个开始:
CREATE TABLE dat3 AS
SELECT url_host, part_1, part_2, part_3, part_4, part_5,
CASE
WHEN part_5 IS NOT NULL THEN part_5
WHEN part_5 IS NULL AND part_4 IS NOT NULL THEN part_4
WHEN part_4 IS NULL AND part_3 IS NOT NULL THEN part_3
WHEN part_3 IS NULL AND part_2 IS NOT NULL THEN part_2
END AS last,
CASE
WHEN part_5 IS NOT NULL THEN concat(part_4, '.', part_5)
WHEN part_5 IS NULL AND part_4 IS NOT NULL THEN concat(part_3, '.', part_4)
WHEN part_4 IS NULL AND part_3 IS NOT NULL THEN concat(part_2, '.', part_3)
END AS two_last,
CASE
WHEN part_5 IS NOT NULL THEN concat(part_3, '.', part_4, '.', part_5)
WHEN part_5 IS NULL AND part_4 IS NOT NULL THEN concat(part_2, '.', part_3, '.', part_4)
END AS three_last,
CASE
WHEN part_5 IS NOT NULL THEN concat(part_2, '.', part_3, '.', part_4, '.', part_5)
END AS four_last
FROM dat2
接下来,将此表转换为“长”格式:
CREATE TABLE dat4 AS
SELECT * FROM
(WITH temp AS (
SELECT url_host, array[last, two_last, three_last, four_last] last_combs
FROM dat3)
SELECT url_host, pattern FROM temp
CROSS JOIN UNNEST(last_combs) as t(pattern))
WHERE pattern IS NOT NULL
现在,将组合与 TLD 列表匹配:
CREATE TABLE dat5 AS
SELECT url_host, max_by(tld, tld_length) tld FROM
(SELECT url_host, pattern, d.tld, length(d.tld) tld_length
FROM dat4 h
LEFT JOIN domains_tld d ON h.pattern = d.tld
WHERE d.tld IS NOT NULL)
GROUP BY url_host
最后,我们从主机中提取域!
SELECT url_host, tld,
regexp_extract(url_host, concat(‘p{Alnum}+.’, tld)) AS sld
FROM dat5