2011-06-14 92 views
16

我需要解析一个URL。我目前使用urlparse.urlparse()和urlparse.urlsplit()。如何在需要时将“http://”协议预先添加到网址中?

问题是,当它不存在该方案时,我无法从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只有在通过 '//'正确引入网址时才会识别netloc 。否则,输入推测为 是一个相对URL,因此用路径组件启动 。

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

我想我可以检查该方案是否存在,如果不存在,则添加它,然后解析它。但是这个解决方案看起来不太好。

你有更好的主意吗?

编辑: 感谢您的所有答案。但是,我不能做科里和其他人提出的“开始”事情。 Becouse,如果我得到一个URL与其他协议/计划我会搞砸了。请参阅:

如果我得到这个网址:

ftp://something.com 

拟议我想补充的“http://”的代码开始,并会搞砸了。

的解决方案,我发现

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

一些需要注意的:

我做一些验证第一,如果没有方法给出我认为这是http://

+0

是这是因为URL的协议部分 - “http://” - 缺失? – ewall 2011-06-14 14:22:34

+0

是的,这就是原因。但是,如果计划仍然失踪,我怎么能得到它? – santiagobasulto 2011-06-14 14:24:31

+0

在你的解决方案中,我仍然检查领先的''/''(可能只是'/'),因为一个合适的url会有这个(即使这个方案丢失) – SingleNegationElimination 2011-06-24 17:26:31

回答

4

该文档具有此确切示例,正好在您粘贴的文本下方。如果不存在,添加'//'会得到你想要的。如果你不知道它是否有协议和'//',你可以使用正则表达式(甚至只是看看它是否包含'//')来确定是否需要添加它。

你的其他选择是使用split('/')并获取它返回的列表的第一个元素,只有当url没有协议或'//'时它才会工作。

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

+0

我仍然有不同的协议问题(请参阅评论Bryan答案)。谢谢 – santiagobasulto 2011-06-14 14:35:05

+0

然后你可以使用正则表达式 - 检查(?:http | ftp | etc):// - 或者检查字符串中是否存在'://'。这取决于你想要它有多强大;完整的URL解析是复杂的。 – SteveMc 2011-06-14 16:19:24

+0

+1你说得对SteveMc。什么会更快?使用您发布的协议列表解析它,或者使用我建议的urlparse进行解析? – santiagobasulto 2011-06-14 19:53:50

2

你是否考虑过在url开头检查“http://”的存在,如果不存在,就添加它?假设第一部分确实是netloc而不是相对url的一部分,另一种解决方案是只抓住所有的东西,直到第一个“/”,并将其用作netloc。

+0

是的,这就是我现在正在做的。但不太喜欢。如果没有更好的出现,我会保持这一点。谢谢! – santiagobasulto 2011-06-14 14:28:17

+0

我还有一个问题。如果使用其他协议/方案呢?如果我在这个URL中检查http://:“ftp:// my.home.com”,那么我会认为它不存在。如果我添加它,我会搞砸 – santiagobasulto 2011-06-14 14:30:37

9

看起来像你需要指定协议获得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 
4

从文档:

继在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' 
0

这一个衬垫会做到这一点。

netloc = urlparse('//' + ''.join(urlparse(url)[1:])).netloc 
4

如果协议是总是HTTP你可以只用一条线:

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

一个更好的选择是使用的协议,如果它pased

​​
+0

你的意思是如果返回url://“in url else”http://“+ url”? – 2014-06-22 23:40:06

+1

感谢罗伯特多德的错误报告。 – 2014-06-23 09:30:56

相关问题