2011-03-20 47 views
10

比較是否有Python來比較兩個URL的標準方法 - 在這個例子中實現are_url_the_same兩個URL在Python

url_1 = 'http://www.foo.com/bar?a=b&c=d' 
url_2 = 'http://www.foo.com:80/bar?c=d;a=b' 

if are_urls_the_same(url_1, url2): 
    print "URLs are the same" 

在同我的意思是,他們訪問同一資源 - 讓兩個網址在這個例子中是一樣的。

+1

雖然主機名稱相同,但由於HTTP默認爲端口80,查詢字符串完全不同。 – 2011-03-20 22:31:28

+0

重新排序查詢參數不一定會導致相同的資源。訂單是可觀察的,並且對於某些(pathalogical)服務可能很明顯。 – SingleNegationElimination 2011-03-20 23:15:19

回答

6

使用urlparse,寫一個比較功能與您需要

>>> from urlparse import urlparse 
>>> o = urlparse('http://www.cwi.nl:80/%7Eguido/Python.html') 

的字段,你可以在任何以下的比較:

  1. 方案0 URL方案說明符
  2. netloc 1網絡位置部分
  3. 路徑2分層路徑
  4. param S代表最後一個路徑元件3個參數
  5. 查詢4查詢部件
  6. 片段5片段標識符
  7. 的用戶名的用戶名
  8. 密碼密碼
  9. 主機名的主機名(小寫)
  10. 端口的端口號爲整數如果存在
+0

好的解決方案。你只需要選擇這十個元素中的哪一個需要相同,以使它們被認爲是相同的。 – 2011-03-20 22:34:45

+0

我是否真的需要推出我自己的產品,並考慮所有的邊緣情況 - 是否沒有像Perl的URI :: eq(http://search.cpan.org/dist/URI/URI.pm)? – EvdB 2011-03-20 22:57:06

10

下面是一個簡單的類,使您能夠做到這一點:

if Url(url1) == Url(url2): 
    pass 

它很容易被改組爲一個功能,雖然這些對象是可哈希的,因此使您能夠使用一組或字典,將它們添加到緩存:

from urlparse import urlparse, parse_qsl 
from urllib import unquote_plus 

class Url(object): 
    '''A url object that can be compared with other url orbjects 
    without regard to the vagaries of encoding, escaping, and ordering 
    of parameters in query strings.''' 

    def __init__(self, url): 
     parts = urlparse(url) 
     _query = frozenset(parse_qsl(parts.query)) 
     _path = unquote_plus(parts.path) 
     parts = parts._replace(query=_query, path=_path) 
     self.parts = parts 

    def __eq__(self, other): 
     return self.parts == other.parts 

    def __hash__(self): 
     return hash(self.parts) 
+1

從上面缺少'urllib import unquote_plus'。否則,這段代碼非常酷!謝謝 - 它爲我節省了一堆時間! – RPM 2013-12-10 00:25:50

+1

幾乎完美。需要考慮這個路徑''/ foo''和''/ foo /''也是一樣的(當然也包括''''和''/'')。 – MaratC 2015-01-20 16:10:41

+0

MaratC'/ foo'和'/ foo /'肯定不是一樣的。當瀏覽器改變爲'/'時,瀏覽器不會將'/ foo'改爲'/ foo /',並且可以引用不同的東西(即foo文件和foo目錄)。 – dalore 2015-05-19 11:20:39