2012-05-14 10 views
9

パスの "./"または "../"部分を削除する、またはデフォルトのポートを追加する、特殊文字をエスケープするなど、PythonでURLを正規化するライブラリ関数を探しています。結果は、同じWebページを指す2つのURLに固有の文字列でなければなりません。例えば、http://google.comhttp://google.com:80/a/../は同じ結果を返します。URLを正規化/正規化しますか?

私はPython 3が好きで、既にurllibモジュールを調べました。 URLを分割する機能はありますが、URLを正規化する機能はありません。 Javaには同様のことを行うURI.normalize()関数があります(デフォルトのポート80は指定されたポートとはみなされません)が、これはPythonのようなものですか?これについて

+0

'ます。http:// google.com /は' 'HTTPと同じではありません://グーグル.com:80/a /../ 'つまり、 '/ a'が存在しなければ、2番目のパスは失敗します。それを "正規化"することによって、特別なケースを失い、無効なもので始まったときに有効なURIで終わる... –

答えて

0

good startに続いて、私はWebによく見られるほとんどのケースに適合する方法を構成しました。

def urlnorm(base, link=''): 
    '''Normalizes an URL or a link relative to a base url. URLs that point to the same resource will return the same string.''' 
    new = urlparse(urljoin(base, url).lower()) 
    return urlunsplit((
    new.scheme, 
    (new.port == None) and (new.hostname + ":80") or new.netloc, 
    new.path, 
    new.query, 
    '')) 
4

方法:

In [1]: from urllib.parse import urljoin 

In [2]: urljoin('http://example.com/a/b/c/../', '.') 
Out[2]: 'http://example.com/a/b/' 

this questionへの回答からインスピレーションを受けています。それはポートを正規化するのではありませんが、それを行う関数を呼び出すのは簡単です。

+0

私は 'urllib.parse'を持っていませんが、私は' urlparse'を持っています。 – osa

+3

'urllib.parse'はPython 3の場所です。元の質問にPy 3について質問しました。 –

4

これは私が使用しているものであり、これまでのところこれまでに働いています。あなたはピルからurlnormを得ることができます。

クエリパラメータを並べ替えることに注意してください。私はこれが不可欠であることを発見しました。

from urlparse import urlsplit, urlunsplit, parse_qsl 
from urllib import urlencode 
import urlnorm 

def canonizeurl(url): 
    split = urlsplit(urlnorm.norm(url)) 
    path = split[2].split(' ')[0] 

    while path.startswith('/..'): 
     path = path[3:] 

    while path.endswith('%20'): 
     path = path[:-3] 

    qs = urlencode(sorted(parse_qsl(split.query))) 
    return urlunsplit((split.scheme, split.netloc, path, qs, '')) 
+0

無効な親ディレクトリを削除しました – hoju

+0

' split [2] .split( '')[0] 'を' urllib.parse.quote(split [2]) ' - 場合によっては、URLに空白があることは完全に正常であり、実際には必要です。 また、urlnormはpy2kのみです –

+0

また、一部の特殊なケースでは、実際には必須のURLコンポーネントであるフラグメントを破棄しています。はい。「blah.com /#wat」がまったく別のページであり、「blah.com /」であるウェブページがゼロではありません。これは一般的にjavascriptで行われ、巨大なPITAですが、存在します。 –

2

urltoolsモジュールはhttp://にダブルスラッシュを台無しにすることなく、複数のスラッシュ、...成分を正規化します。あなたがpip install urltoolsを行うたら、次のように

は使い方がある:サイドノート、などのリソースとして

print urltools.normalize('http://domain.com:80/a////b/../c') 
>>> 'http://domain.com/a/c'