必要に応じて、「http://」プロトコルをURLにプレップするにはどうすればよいですか? [複製
-
27-10-2019 - |
質問
この質問にはすでに答えがあります:
URLを解析する必要があります。現在、urlparse.urlparse()およびurlparse.urlsplit()を使用しています。
問題は、スキームが提示されていない場合、URLから「netloc」(ホスト)を取得できないことです。つまり、次のURLがある場合:
www.amazon.com/programming-python-mark-lutz/dp/0596158106/ref=sr_1_1?ie=utf8&qid=1308060974&sr=8-1
netloc:www.amazon.comを入手できません
Python Docsによると:
RFC 1808の構文仕様に従って、urlparseは「//」によって適切に導入された場合にのみNetlocを認識します。それ以外の場合、入力は相対URLであると推定されているため、パスコンポーネントから開始します。
だから、それは意図的にこの方法です。しかし、私はまだそのURLからNetlocを取得する方法を知りません。
スキームが存在するかどうか、そうでない場合は、追加してから解析できると思います。しかし、このソリューションは本当に良くないようです。
もっと良いアイデアはありますか?
編集:すべての答えをありがとう。しかし、私はコーリーなどによって提案されている「スタートスイス」のことをすることはできません。他のプロトコル/スキームでURLを取得した場合、私はそれを台無しにします。見る:
このURLを取得した場合:
ftp://something.com
提案されたコードを使用すると、「http://」を開始に追加し、それを台無しにします。
私が見つけた解決策
if not urlparse.urlparse(url).scheme:
url = "http://"+url
return urlparse.urlparse(url)
注意すべきこと:
私は最初にいくつかの検証をします、そしてスキームが与えられない場合、私はそれがhttp://であると考えます
解決
ドキュメントには、貼り付けたテキストのすぐ下にあるこの正確な例があります。 「//」を追加していない場合は、必要なものが得られます。プロトコルと「//」があるかどうかがわからない場合は、Regexを使用して(または既に「//」が含まれているかどうかを確認して、追加する必要があるかどうかを判断できます。
他のオプションは、split( '/')を使用し、返されるリストの最初の要素を使用することです。これは、URLにプロトコルまたは「//」がない場合にのみ機能します。
編集(将来の読者向けの追加):プロトコルを検出するための正規表現は次のようなものです re.match('(?:http|ftp|https)://', url)
他のヒント
Netlocを取得するには、プロトコルを指定する必要があるようです。
存在しない場合は、次のように見えるかもしれません。
import urlparse
url = 'www.amazon.com/Programming-Python-Mark-Lutz'
if '//' not in url:
url = '%s%s' % ('http://', url)
p = urlparse.urlparse(url)
print p.netloc
ドキュメントから:
RFC 1808の構文仕様に従って、urlparseは「//」によって適切に導入された場合にのみNetlocを認識します。それ以外の場合、入力は相対URLであると推定されているため、パスコンポーネントから開始します。
だからあなたはただできる:
In [1]: from urlparse import urlparse
In [2]: def get_netloc(u):
...: if not u.startswith('http'):
...: u = '//' + u
...: return urlparse(u).netloc
...:
In [3]: get_netloc('www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/ref=sr_1_1?ie=UTF8&qid=1308060974&sr=8-1')
Out[3]: 'www.amazon.com'
In [4]: get_netloc('http://www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/ref=sr_1_1?ie=UTF8&qid=1308060974&sr=8-1')
Out[4]: 'www.amazon.com'
In [5]: get_netloc('https://www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/ref=sr_1_1?ie=UTF8&qid=1308060974&sr=8-1')
Out[5]: 'www.amazon.com'
プロトコルの場合 常にhttp 1つの行のみを使用できます。
return "http://" + url.split("://")[-1]
より良いオプションはそうです プロトコルが通過した場合は、プロトコルを使用します:
return url if "://" in url else "http://" + url
URLの開始時に「http://」の存在をチェックするだけで、そこにない場合は追加しましたか?別の解決策は、最初の部分が実際にNetlocであり、相対URLの一部ではないと仮定することで、すべてを最初の「/」までつかみ、それをNetlocとして使用することです。
この1つのライナーはそれをします。
netloc = urlparse('//' + ''.join(urlparse(url)[1:])).netloc