Python中的规范URL比较?
在Python中有什么工具可以进行URL比较吗 例如,如果我有Python中的规范URL比较?,python,fuzzy-comparison,Python,Fuzzy Comparison,在Python中有什么工具可以进行URL比较吗 例如,如果我有http://google.com和google.com/我想知道它们很可能是同一个站点 如果手动构造规则,我可能会将其大写,然后去掉http://部分,并删除最后一个字母数字字符后面的任何内容。。但我可以看到这方面的失败,我相信你也可以 有这样的图书馆吗?你会怎么做?它不是“模糊的”,它只是找到两个字符串之间的“距离”: 我将删除所有对URL解析有语义意义的部分(协议、斜杠等),将其规范化为小写,然后执行levenstein距离,
http://google.com
和google.com/
我想知道它们很可能是同一个站点
如果手动构造规则,我可能会将其大写,然后去掉http://
部分,并删除最后一个字母数字字符后面的任何内容。。但我可以看到这方面的失败,我相信你也可以
有这样的图书馆吗?你会怎么做?它不是“模糊的”,它只是找到两个字符串之间的“距离”: 我将删除所有对URL解析有语义意义的部分(协议、斜杠等),将其规范化为小写,然后执行levenstein距离,然后从中确定多少差异是可接受的阈值
只是一个想法。这是我脑子里想出来的:
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)
很明显,这里有很多空间来处理这个问题。正则表达式可能比startswith和endswith更好,但你明白了。你可以使用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中的其他标准参数,例如。这是有用的
将其与以下内容相结合:
代码:
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']
结果:
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']
它不会让你在没有X信誉的情况下发布两个链接,但是如果你把URL放在反引号中,那么你可以包含任意多的URL,这样解析器就不会将它们转换为链接。我编辑你的问题是为了说明我认为你的意思,但如果我弄错了,请再次编辑以纠正我。哦,还有一件事:你所说的“模糊”比较到底是什么意思?很容易看出
http://google.com
和google.com/
是一回事,因为它们有完全相同的规范形式,但这不是模糊比较。一个真正的模糊比较会识别出相似但不完全相同的URL,即使在你将它们转换成标准格式之后也是如此。谢谢,这还是很新鲜的。我改变了标题。看起来这可能是一个很好的起点。这类似于我要手动创建的。我希望有一个lib已经做到了这一点。科林:这似乎是一个应该解决的问题。@Colin:这是一件自己动手做通常很容易的事情,而且更有可能得到你真正想要的东西。问题是,URL没有严格定义的“标准形式”,所以每个想要它的人都会有一些不同的想法。我同意Nicholas的观点:这不够明确,无法得到标准定义。如果你自己写的话,你会得到最好的服务。我觉得整个URL的大小写是个坏主意——大小写在URL中很重要(主机和域除外)