21

我需要解析一个 URL。我目前正在使用 urlparse.urlparse() 和 urlparse.urlsplit()。

问题是当它不存在方案时,我无法从 URL 获取“netloc”(主机)。我的意思是,如果我有以下网址:

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文档:

遵循 RFC 1808 中的语法规范,urlparse 只有当它被 '//' 正确引入时才能识别它。否则,输入被假定为相对 URL,因此以路径组件开始。

所以,这是故意的。但是,我仍然不知道如何从该 URL 获取 netloc。

我想我可以检查该方案是否存在,如果不存在,则添加它,然后解析它。但是这个解决方案似乎并不是很好。

你有更好的主意吗?

编辑: 感谢所有的答案。但是,我不能做 Corey 和其他人提出的“startswith”事情。因为,如果我得到一个带有其他协议/方案的 URL,我会把它搞砸。看:

如果我得到这个网址:

ftp://something.com

使用建议的代码,我将在开头添加“http://”并将其搞砸。

我找到的解决方案

if not urlparse.urlparse(url).scheme:
   url = "http://"+url
return urlparse.urlparse(url)

需要注意的一点:

我先做一些验证,如果没有给出方案,我认为它是 http://

4

6 回答 6

12

看起来您需要指定协议才能获得 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

有关该问题的更多信息:https ://bugs.python.org/issue754016

于 2011-06-14T15:08:08.027 回答
6

该文档有这个确切的示例,就在您粘贴的文本下方。添加'//'如果它不存在将得到你想要的。如果您不知道它是否有协议和“//”,您可以使用正则表达式(或者甚至只是查看它是否已经包含“//”)来确定是否需要添加它。

您的另一个选择是使用 split('/') 并获取它返回的列表的第一个元素,这仅在 url 没有协议或“//”时才有效。

编辑(为未来的读者添加):用于检测协议的正则表达式类似于re.match('(?:http|ftp|https)://', url)

于 2011-06-14T14:27:45.643 回答
6

如果协议始终为 http,则只能使用一行:

return "http://" + url.split("://")[-1]

一个更好的选择是使用该协议,如果它通过了

return url if "://" in url else "http://" + url
于 2014-03-20T11:19:52.657 回答
5

从文档:

遵循 RFC 1808 中的语法规范,urlparse 只有当它被 '//' 正确引入时才能识别它。否则,输入被假定为相对 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'
于 2011-06-14T15:13:37.877 回答
2

您是否考虑过仅检查 URL 开头是否存在“http://”,如果不存在则添加它?另一个解决方案,假设第一部分确实是 netloc 而不是相对 url 的一部分,是只抓取第一个“/”之前的所有内容并将其用作 netloc。

于 2011-06-14T14:27:10.713 回答
0

这一个班轮会做到这一点。

netloc = urlparse('//' + ''.join(urlparse(url)[1:])).netloc
于 2013-04-05T23:52:35.317 回答