Python中的规范URL比较?

时间:2010-07-19 21:36:09

标签: python fuzzy-comparison

是否有任何工具可以在Python中进行URL比较?

例如,如果我有http://google.comgoogle.com/,我想知道它们可能是同一个网站。

如果我要手动构建一个规则,我可以将其大写,然后剥离http://部分,并删除最后一个字母数字字符后的任何内容。但我可以看到这个失败,因为我我相信你也可以。

有没有这样做的图书馆?你会怎么做?

4 个答案:

答案 0 :(得分:3)

这是我的头顶:

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)
显然,有更多摆弄这个的空间。正则表达可能比开头和结尾更好,但你明白了。

答案 1 :(得分:2)

您可以使用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')]

答案 2 :(得分:0)

显然有quite a bit to creating a canonical urlurl-normalize库是我测试过的最好的库。

根据URL的来源,您可能希望清除它们的其他标准参数,例如UTM codesw3lib.url.url_query_cleaner对此很有用。

将其与Ned Batchelder's answer组合起来可能类似于:

代码:

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']

答案 3 :(得分:-1)

它不是“模糊”,只是找到两个字符串之间的“距离”:

http://pypi.python.org/pypi/python-Levenshtein/

我会删除对URL解析(协议,斜杠等)具有语义意义的所有部分,规范化为小写,然后执行levenstein距离,然后从那里确定有多少差异是可接受的阈值。

只是一个想法。