我正在开发一个项目,经常需要检查两个网址之间的相似度分数,最初我通过从网页中抓取所有文本,然后计算文档相似度来做到这一点。然而,这确实很耗时,相反,我正在寻找一种方法,只需使用 url 的内容而不是遍历所有文本即可检测 url 之间的相似性。
eg:
url1: https://en.wikipedia.org/wiki/Tic-tac-toe
url2: https://en.wikipedia.org/wiki/Chess
a rough similarity estimate : 67% (since both are from wiki and both are related to games)
您最好比较各个 URL 片段,因为 foo.com/a/b/c 和 boo.com/a/b/c 具有相似的序列分数,但可能具有非常不同的内容。
为此,您可以使用:
urllib.parse.urlparse()
将 url 分成不同的部分,例如 netloc(域)、路径和参数difflib.SequenceMatcher
可以判断两个字符串有多相似。w3lib.url.canonicalize_url
标准化您的网址,因为不同的参数顺序等会导致相同的内容,尽管看起来非常不同。有关更多信息,请参阅 w3lib 文档。from difflib import SequenceMatcher
from w3lib.url import canonicalize_url
from urllib.parse import urlparse
def compare_urls(url1, url2):
url1 = canonicalize_url(url1)
url2 = canonicalize_url(url2)
url1_parsed = urlparse(url1)
url2_parsed = urlparse(url2)
domain = SequenceMatcher(None, url1_parsed.netloc, url2_parsed.netloc).ratio()
path = SequenceMatcher(None, url1_parsed.path, url2_parsed.path).ratio()
query = SequenceMatcher(None, url1_parsed.query, url2_parsed.query).ratio()
return {
"domain": domain,
"path": path,
"query": query,
}
if __name__ == "__main__":
print(compare_urls(
"https://en.wikipedia.org/wiki/Tic-tac-toe",
"https://en.wikipedia.org/wiki/Chess"
))
# prints: {'domain': 1.0, 'path': 0.5, 'query': 1.0}
通过将序列比较与 netloc(域)、路径和参数分开,您可以为它们中的每一个分配分数权重,以设计更成功的比较算法。
如果您将其存储在数据库中,我肯定会推荐 Levenshtein 距离函数。
例如,将其与 postgres 一起使用:
安装:
CREATE EXTENSION IF NOT EXISTS pg_trgm;
搜索:
SELECT
url,
LEVENSHTEIN(url, %s) AS similarity
FROM
url_table
ORDER BY
similarity;