我正在遍历一系列 URL 并想要清理它们。我有以下代码:
# Parse url to remove http, path and check format
o_url = URI.parse(node.attributes['href'])
# Remove www
new_url = o_url.host.gsub('www.', '').strip
如何扩展它以删除某些 URL 中存在的子域?
我刚刚编写了一个名为 Domainatrix 的库来执行此操作。你可以在这里找到它:http: //github.com/pauldix/domainatrix
require 'rubygems'
require 'domainatrix'
url = Domainatrix.parse("http://www.pauldix.net")
url.public_suffix # => "net"
url.domain # => "pauldix"
url.canonical # => "net.pauldix"
url = Domainatrix.parse("http://foo.bar.pauldix.co.uk/asdf.html?q=arg")
url.public_suffix # => "co.uk"
url.domain # => "pauldix"
url.subdomain # => "foo.bar"
url.path # => "/asdf.html?q=arg"
url.canonical # => "uk.co.pauldix.bar.foo/asdf.html?q=arg"
这是一个棘手的问题。一些顶级域不接受二级注册。
比较example.com
和example.co.uk
。如果您只是简单地剥离除最后两个域之外的所有内容,那么您最终会得到example.com
, 和co.uk
,这绝不是意图。
Firefox 通过有效的顶级域过滤解决了这个问题,他们维护了所有这些域的列表。更多信息请访问publicsuffix.org。
您可以使用此列表过滤除有效 TLD 旁边的域之外的所有内容。我不知道有任何 Ruby 库可以做到这一点,但发布一个是个好主意!
更新:有C、Perl 和 PHP 库可以做到这一点。给定 C 版本,您可以创建一个 Ruby 扩展。或者,您可以将代码移植到 Ruby。
对于后代,这是 2014 年 10 月的更新:
我正在寻找一个更新的依赖项来依赖并找到了 public_suffix gem ( RubyGems ) ( GitHub )。它正在积极维护,并通过维护已知公共后缀列表来处理所有顶级域和嵌套子域问题。
结合 URI.parse 来剥离协议和路径,效果非常好:
❯❯❯ 2.1.2 ❯ PublicSuffix.parse(URI.parse('https://subdomain.google.co.uk/path/on/path').host).domain
=> "google.co.uk"
您在这里需要的正则表达式可能有点棘手,因为主机名可能非常复杂——您可以有多个子域(即 foo.bar.baz.com),或者顶级域 (TLD) 可以有多个部分(即 www.baz.co.uk)。
准备好复杂的正则表达式了吗?:)
re = /^(?:(?>[a-z0-9-]*\.)+?|)([a-z0-9-]+\.(?>[a-z]*(?>\.[a-z]{2})?))$/i
new_url = o_url.host.gsub(re, '\1').strip
让我们把它分成两个部分。^(?:(?>[a-z0-9-]*\.)+?|)
将通过匹配一组或多组字符后跟一个点来收集子域(贪婪地,以便在此处匹配所有子域)。如果没有子域(如 foo.com),则需要空交替。([a-z0-9-]+\.(?>[a-z]*(?>\.[a-z]{2})?))$
将收集实际的主机名和 TLD。它允许使用单部分 TLD(如 .info、.com 或 .museum)或两部分 TLD,其中第二部分是两个字符(如 .oh.us 或 .org.uk)。
我在以下样本上测试了这个表达式:
foo.com => foo.com
www.foo.com => foo.com
bar.foo.com => foo.com
www.foo.ca => foo.ca
www.foo.co.uk => foo.co.uk
a.b.c.d.e.foo.com => foo.com
a.b.c.d.e.foo.co.uk => foo.co.uk
请注意,此正则表达式不会正确地将具有两个以上“部分”的主机名与 TLD 匹配!
就像是:
def remove_subdomain(host)
# Not complete. Add all root domain to regexp
host.sub(/.*?([^.]+(\.com|\.co\.uk|\.uk|\.nl))$/, "\\1")
end
puts remove_subdomain("www.example.com") # -> example.com
puts remove_subdomain("www.company.co.uk") # -> company.co.uk
puts remove_subdomain("www.sub.domain.nl") # -> domain.nl
您仍然需要添加您认为是根域的所有(根)域。所以“.uk”可能是根域,但您可能希望将主机保留在“.co.uk”部分之前。
从一般意义上来说,检测 URL 的子域并非易事——如果您只考虑基本的子域,这很容易,但是一旦您进入国际领域,这就变得很棘手。
编辑:考虑像http://mylocalschool.k12.oh.us等的东西。
为什么不直接去掉 .com 或 .co.uk,然后在 '.' 上拆分?并获得最后一个元素?
some_url.host.sub(/(\.co\.uk|\.[^.]*)$/).split('.')[-1] + $1
不得不说这感觉很hacky。有没有像 .co.uk 这样的其他域名?
多年来,我在编写各种杂乱无章的爬虫和刮板时为此苦苦挣扎。我最喜欢解决这个问题的 gem 是 Pete Gamache 的 FuzzyUrl:https ://github.com/gamache/fuzzyurl 。它可用于 Ruby、JavaScript 和 Elixir。