如何在Python中将URL字符串分割成单独的部分?

19

我决定今晚开始学习 Python :) 我对 C 语言相当熟悉(写过一个操作系统),所以在编程方面算不上是新手,Python 的一切看起来都非常简单。但我不知道如何解决这个问题: 假设我有这个地址:

http://example.com/random/folder/path.html

那么我该怎么样从中创建两个字符串呢?一个包含服务器的“基本”名称,例如:

http://example.com/

还有一个包含路径中不包括最后一个文件名的部分,例如:

http://example.com/random/folder/

当然,我知道可以通过查找第三个和最后一个斜杠来实现,但是否有更好的方法呢?

同时,在这两种情况下,末尾的斜杠都很酷,但我并不介意,因为它可以很容易地添加。 那么是否有一个好的、快速有效的解决方案呢?或者只有“我的”解决方案,查找斜杠?


你可能想要用代码分享你的解决方案。 - monkut
2
明天回来告诉我们进展如何。我猜你只是在用Python写C代码,而不是真正的Python代码 :-). - paxdiablo
4
你提到了它,你写过哪个操作系统? - tzot
你可以在这里找到一个Python正则表达式,用于部分拆分(即URL、方案、域名、顶级域名、端口和查询路径):https://dev59.com/WWkw5IYBdhLWcg3wn7-O#31952097 - Paolo Rovelli
6个回答

57

在 Python 2.x 中使用 urlparse 模块(或在 Python 3.x 中使用 urllib.parse)即可实现。

>>> from urllib.parse import urlparse
>>> url = 'http://example.com/random/folder/path.html'
>>> parse_object = urlparse(url)
>>> parse_object.netloc
'example.com'
>>> parse_object.path
'/random/folder/path.html'
>>> parse_object.scheme
'http'
>>>

如果您想在URL文件路径上进行更多操作,可以使用 posixpath 模块:

>>> from posixpath import basename, dirname
>>> basename(parse_object.path)
'path.html'
>>> dirname(parse_object.path)
'/random/folder'

之后,您可以使用posixpath.join将这些部分拼接在一起。

注意:Windows用户可能会在os.path中的路径分隔符上出现问题。 posixpath模块文档有一个特殊的参考URL操作,所以一切都好。


2
在urlparse上+1,但不要使用os.path来操作.path部分。os.path的处理因操作系统而异,而URI始终使用“/”作为路径部分分隔符。 - bobince
1
是的,移除 os.path 部分。可以考虑使用 posixpath 模块替代。这样我会支持你的。 - nosklo
2
哎呀,我完全错过了那个。我好久没用 Windows 了 :|。已修复。 - sykora
为了方便参考,这里是 Py 2 的过程:import urlparse; parse_object = urlparse.urlparse(url) - patrick
Windows用户会被“卡死”,我认为这是因为在Linux出现之前,路径指定符就已经存在了 :) - J. Gwinner

12
如果您只需要解析URL的这个部分,Python内置的rpartition函数就可以胜任:
>>> URL = "http://example.com/random/folder/path.html"
>>> Segments = URL.rpartition('/')
>>> Segments[0]
'http://example.com/random/folder'
>>> Segments[2]
'path.html'

来自Pydoc,str.rpartition:

将字符串在最后一个分隔符处分割,并返回一个包含分隔符前面部分、分隔符本身和分隔符后面部分的3元组。如果找不到分隔符,则返回一个包含两个空字符串和字符串本身的3元组。

这意味着rpartition为您进行搜索,并在指定字符(在本例中为/)的最后(最右侧)出现时将字符串拆分。它返回一个包含以下内容的元组:

(everything to the left of char , the character itself , everything to the right of char)

我知道每个人都会(有很好的理由)建议使用像urllib这样的库来处理这种情况,但在这种情况下,我有一种情感上的偏好。就我所看到的,这种方法将是完全可靠的。对于这种有限的情况,不需要进行任何复杂的解析。只要传入的URL格式正确,就应该保证路径从第三个斜杠字符开始。我被它吸引,因为它看起来更简单、更快速,而且不需要导入库,但如果我错了,我也准备接受纠正。 - NeilG
Pydoc链接已损坏(404)。 - Peter Mortensen
'sep'是什么?一个简单(固定)的字符串吗?还是一个正则表达式? - Peter Mortensen

10

我对Python没有经验,但我找到了urlparse模块,它应该能够完成这项工作。


8
在Python中,许多操作都使用列表完成。 urlparse 模块由Sebasian Dietz提到可能会解决您的具体问题,但如果您通常对寻找字符串中的斜杠等问题感兴趣,则可以尝试类似以下方式:
url = 'http://example.com/random/folder/path.html'

# Create a list of each bit between slashes
slashparts = url.split('/')

# Now join back the first three sections 'http:', '' and 'example.com'
basename = '/'.join(slashparts[:3]) + '/'

# All except the last one
dirname = '/'.join(slashparts[:-1]) + '/'

print 'slashparts = %s' % slashparts
print 'basename = %s' % basename
print 'dirname = %s' % dirname

该程序的输出如下:
slashparts = ['http:', '', 'example.com', 'random', 'folder', 'path.html']
basename = http://example.com/
dirname = http://example.com/random/folder/
有趣的部分是 splitjoin,切片表示法数组[A:B](包括从末尾偏移的负数),作为奖励,字符串上的% 运算符可提供类似于printf 的格式化。

2

看起来 posixpath 模块 在 sykora 的回答中提到 在我的 Python 环境(Python 2.7.3)中不可用。

根据 这篇文章,似乎“正确”的方法是使用...

  • urlparse.urlparseurlparse.urlunparse 可以用于分离和重新附加 URL 的基础部分
  • os.path 的函数可以用于操作路径
  • urllib.url2pathnameurllib.pathname2url(使路径名操作可移植,因此可以在 Windows 等上工作)

因此,例如(不包括重新附加基本 URL)...

>>> import urlparse, urllib, os.path
>>> os.path.dirname(urllib.url2pathname(urlparse.urlparse("http://example.com/random/folder/path.html").path))
'/random/folder'

doughellmann.com的链接已经失效:“404. 页面未找到” - Peter Mortensen

1
您可以使用Python的库furl
f = furl.furl("http://example.com/random/folder/path.html")
print(str(f.path))  # '/random/folder/path.html'
print(str(f.path).split("/")) # ['', 'random', 'folder', 'path.html']

要访问第一个“/”后的单词,请使用:

str(f.path).split("/") # 'random'

关于“Python的库”:但不是标准库的一部分。 - Peter Mortensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接