PythonでURLを正規化する方法を知りたいのですが。
たとえば、次のようなURL文字列がある場合: " http://www.example.com/foo goo / bar.html"
余分なスペース(またはその他の正規化されていない文字)を適切なURLに変換するPythonのライブラリが必要です。
PythonでURLを正規化する方法を知りたいのですが。
たとえば、次のようなURL文字列がある場合: " http://www.example.com/foo goo / bar.html"
余分なスペース(またはその他の正規化されていない文字)を適切なURLに変換するPythonのライブラリが必要です。
このモジュールを見てください: werkzeug.utils。(現在werkzeug.urls
)
探している関数は「url_fix」と呼ばれ、次のように機能します。
>>> from werkzeug.urls import url_fix
>>> url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)')
'http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29'
Werkzeug では次のように実装されています。
import urllib
import urlparse
def url_fix(s, charset='utf-8'):
"""Sometimes you get an URL by a user that just isn't a real
URL because it contains unsafe characters like ' ' and so on. This
function can fix some of the problems in a similar way browsers
handle data entered by the user:
>>> url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)')
'http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29'
:param charset: The target charset for the URL if the url was
given as unicode string.
"""
if isinstance(s, unicode):
s = s.encode(charset, 'ignore')
scheme, netloc, path, qs, anchor = urlparse.urlsplit(s)
path = urllib.quote(path, '/%')
qs = urllib.quote_plus(qs, ':&=')
return urlparse.urlunsplit((scheme, netloc, path, qs, anchor))
正しい解決策は次のとおりです。
# percent encode url, fixing lame server errors for e.g, like space
# within url paths.
fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]")
urllib.quote
または_urllib.quote_plus
urllibのドキュメントから:
quote(文字列[, 安全])
「%xx」エスケープを使用して、文字列内の特殊文字を置き換えます。文字、数字、および文字 "_.-" は決して引用符で囲まれません。オプションの safe パラメータは、引用符で囲んではならない追加の文字を指定します。デフォルト値は「/」です。
例:
quote('/~connolly/')
利回り'/%7econnolly/'
。quote_plus(文字列[, 安全])
quote() と同様ですが、HTML フォームの値を引用するために必要なように、スペースをプラス記号に置き換えます。元の文字列のプラス記号は、セーフに含まれていない限りエスケープされます。また、「/」への安全なデフォルトもありません。
編集: @ΤΖΩΤΖΙΟΥ が指摘するように、URL 全体で urllib.quote または urllib.quote_plus を使用すると、それが壊れます。
>>> quoted_url = urllib.quote('http://www.example.com/foo goo/bar.html')
>>> quoted_url
'http%3A//www.example.com/foo%20goo/bar.html'
>>> urllib2.urlopen(quoted_url)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\python25\lib\urllib2.py", line 124, in urlopen
return _opener.open(url, data)
File "c:\python25\lib\urllib2.py", line 373, in open
protocol = req.get_type()
File "c:\python25\lib\urllib2.py", line 244, in get_type
raise ValueError, "unknown url type: %s" % self.__original
ValueError: unknown url type: http%3A//www.example.com/foo%20goo/bar.html
@ΤΖΩΤΖΙΟΥ は、urlparse.urlparse と urlparse.urlunparseを使用して URL を解析し、パスのみをエンコードする関数を提供します。これはあなたにとってより便利かもしれませんが、既知のプロトコルとホストから URL を構築しているが疑わしいパスを使用している場合は、おそらく urlparse を回避し、URL の疑わしい部分を引用して、既知の安全な部品。
このページはこのトピックに関する Google 検索の上位の結果であるため、Python を使用した URL の正規化で行われた、スペース文字の urlencoding を超えるいくつかの作業について言及する価値があると思います。たとえば、デフォルトのポート、大文字と小文字、末尾のスラッシュの欠如などを処理します。
Atom シンジケーション形式が開発されていたとき、URL を標準形式に正規化する方法について議論がありました。これは、Atom/Pie wikiの記事PaceCanonicalIdsに記載されています。この記事では、いくつかの優れたテスト ケースを提供しています。
この議論の結果の 1 つが、Mark Nottingham のurlnorm.pyライブラリだったと思います。これは、いくつかのプロジェクトで使用して良い結果をもたらしました。ただし、このスクリプトは、この質問で指定された URL では機能しません。そのため、その URL を処理するSam Ruby のバージョンの urlnorm.pyと、前述の Atom wiki のすべてのテスト ケースを選択することをお勧めします。
from urllib.parse import urlparse, urlunparse, quote
def myquote(url):
parts = urlparse(url)
return urlunparse(parts._replace(path=quote(parts.path)))
>>> myquote('https://www.example.com/~user/with space/index.html?a=1&b=2')
'https://www.example.com/~user/with%20space/index.html?a=1&b=2'
import urlparse, urllib
def myquote(url):
parts = urlparse.urlparse(url)
return urlparse.urlunparse(parts[:2] + (urllib.quote(parts[2]),) + parts[3:])
>>> myquote('https://www.example.com/~user/with space/index.html?a=1&b=2')
'https://www.example.com/%7Euser/with%20space/index.html?a=1&b=2'
これは、パスコンポーネントのみを引用します。
参考までに、urlnorm は github に移動しました: http://gist.github.com/246089
このような問題が発生しました。スペースのみを引用する必要があります。
fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]")
役に立ちますが、複雑すぎます。
だから私は簡単な方法を使用しました: url = url.replace(' ', '%20')
、それは完璧ではありませんが、最も簡単な方法であり、この状況で機能します。