是否有任何工具可以在 Python 中进行 URL 比较?
例如,如果我有http://google.com
并且google.com/
我想知道它们很可能是同一个站点。
如果我要手动构建规则,我可能会将其大写,然后剥离该http://
部分,并在最后一个字母数字字符之后删除任何内容。但我可以看到这个失败,我相信你也可以。
有没有这样做的图书馆?你会怎么做?
是否有任何工具可以在 Python 中进行 URL 比较?
例如,如果我有http://google.com
并且google.com/
我想知道它们很可能是同一个站点。
如果我要手动构建规则,我可能会将其大写,然后剥离该http://
部分,并在最后一个字母数字字符之后删除任何内容。但我可以看到这个失败,我相信你也可以。
有没有这样做的图书馆?你会怎么做?
这在我脑海中浮现:
def canonical_url(u):
u = u.lower()
if u.startswith("http://"):
u = u[7:]
if u.startswith("www."):
u = u[4:]
if u.endswith("/"):
u = u[:-1]
return u
def same_urls(u1, u2):
return canonical_url(u1) == canonical_url(u2)
显然,还有很多空间可以摆弄这个。正则表达式可能比开始和结束更好,但你明白了。
您可以使用 dns 查找名称,看看它们是否指向相同的 ip。可能需要进行一些次要的字符串处理以删除令人困惑的字符。
from socket import gethostbyname_ex
urls = ['http://google.com','google.com/','www.google.com/','news.google.com']
data = []
for orginalName in urls:
print 'url:',orginalName
name = orginalName.strip()
name = name.replace( 'http://','')
name = name.replace( 'http:','')
if name.find('/') > 0:
name = name[:name.find('/')]
if name.find('\\') > 0:
name = name[:name.find('\\')]
print 'dns lookup:', name
if name:
try:
result = gethostbyname_ex(name)
except:
continue # Unable to resolve
for ip in result[2]:
print 'ip:', ip
data.append( (ip, orginalName) )
print data
结果:
url: http://google.com
dns lookup: google.com
ip: 66.102.11.104
url: google.com/
dns lookup: google.com
ip: 66.102.11.104
url: www.google.com/
dns lookup: www.google.com
ip: 66.102.11.104
url: news.google.com
dns lookup: news.google.com
ip: 66.102.11.104
[('66.102.11.104', 'http://google.com'), ('66.102.11.104', 'google.com/'), ('66.102.11.104', 'www.google.com/'), ('66.102.11.104', 'news.google.com')]
显然,创建一个规范的 url有很多工作要做。url-normalize库是我测试过的最好的库。
根据您的 url 的来源,您可能希望清除它们的其他标准参数,例如UTM 代码。w3lib.url.url_query_cleaner对此很有用。
将此与Ned Batchelder 的答案结合起来可能类似于:
代码:
from w3lib.url import url_query_cleaner
from url_normalize import url_normalize
urls = ['google.com',
'google.com/',
'http://google.com/',
'http://google.com',
'http://google.com?',
'http://google.com/?',
'http://google.com//',
'http://google.com?utm_source=Google']
def canonical_url(u):
u = url_normalize(u)
u = url_query_cleaner(u,parameterlist = ['utm_source','utm_medium','utm_campaign','utm_term','utm_content'],remove=True)
if u.startswith("http://"):
u = u[7:]
if u.startswith("https://"):
u = u[8:]
if u.startswith("www."):
u = u[4:]
if u.endswith("/"):
u = u[:-1]
return u
list(map(canonical_url,urls))
结果:
['google.com',
'google.com',
'google.com',
'google.com',
'google.com',
'google.com',
'google.com',
'google.com']
这不是“模糊”,它只是找到两个字符串之间的“距离”:
http://pypi.python.org/pypi/python-Levenshtein/
我将删除对 URL 解析(协议、斜杠等)具有语义意义的所有部分,标准化为小写,然后执行 levenstein 距离,然后从那里决定有多少差异是可接受的阈值。
只是一个想法。