如何在Python中获取URL的基础?

如何在Python中获取URL的基础?,python,python-3.x,Python,Python 3.x,我试图确定URL的基础,或者除了页面和参数之外的所有内容。我试过使用split,但是有没有比把它拆分成碎片更好的方法呢?有没有办法删除最后一个“/”中的所有内容 鉴于此: 我想: 首先,您可以使用: 它不是显式地用于URL,但它恰好在URL上工作(即使在Windows上),它只是没有留下尾随斜杠(您可以自己添加它) 您可能还希望查看更细粒度的解析;如果URL包含查询字符串或散列,您可能希望将其解析为多个部分,修剪解析返回的路径组件,然后重新组合,以便在不丢失查询和散列信息的情况下修剪路径 最后

我试图确定URL的基础,或者除了页面和参数之外的所有内容。我试过使用split,但是有没有比把它拆分成碎片更好的方法呢?有没有办法删除最后一个“/”中的所有内容

鉴于此:

我想:

首先,您可以使用:

它不是显式地用于URL,但它恰好在URL上工作(即使在Windows上),它只是没有留下尾随斜杠(您可以自己添加它)

您可能还希望查看更细粒度的解析;如果URL包含查询字符串或散列,您可能希望将其解析为多个部分,修剪解析返回的
路径
组件,然后重新组合,以便在不丢失查询和散列信息的情况下修剪路径

最后,如果您想在最后一条斜线后拆分组件,可以使用
1
maxplit
执行一次操作,并保留第一个组件:

>>> 'http://127.0.0.1/asdf/login.php'.rsplit('/', 1)[0]
'http://127.0.0.1/asdf'

获取最正确的斜杠出现次数;在原始字符串中的该位置使用字符串切片。+1将在末尾获得最后一个斜杠

link = "http://127.0.0.1/asdf/login.php"
link[:link.rfind('/')+1]

无需使用正则表达式,只需使用
rsplit()


最好的方法是使用

从文档中:

该模块的设计目的是与相关网络上的互联网RFC相匹配 统一资源定位器。它支持以下URL方案:
file
ftp
gopher
hdl
http
https
imap
mailto
mms
news
nntp
prospero
rsync
rtsp
rtspu
sftp
shttp
sip
snews
svn
svn+ssh
telnet
wais
ws
wss

您可能希望使用和执行以下操作:


如果使用python3,则可以使用urlparse和urlparse

In :from urllib.parse import urlparse, urlunparse

In :url = "http://127.0.0.1/asdf/login.php"

In :result = urlparse(url)

In :new = list(result)

In :new[2] = new[2].replace("login.php", "")

In :urlunparse(new)
Out:'http://127.0.0.1/asdf/'

使用urllib库有Python3的最短解决方案(不知道是否最快):

请记住,urllib库支持与HTML关键字兼容的uri/url。这意味着以“/”结尾的uri/url与此处不带like的uri/url不同:


这是指向用于python的urllib的链接:

当您使用URLSPILT时,它将返回一个SplitResult对象:

from urllib.parse import urlsplit
split_url = urlsplit('http://127.0.0.1/asdf/login.php')
print(split_url)

>>> SplitResult(scheme='http' netloc='127.0.0.1' path='/asdf/login.php' query='' fragment='') 
您可以创建自己的SplitResult()对象并将其传递给urlunsplit。这段代码应该适用于多个url拆分,无论其长度如何,只要您知道您想要的最后一个path元素是什么

from urllib.parse import urlsplit, urlunsplit, SplitResult

# splitting url:
split_url = urlsplit('http://127.0.0.1/asdf/login.php')

# editing the variables you want to change (in this case, path):    
last_element = 'asdf'   # this can be any element in the path.
path_array = split_url.path.split('/')

# print(path_array)
# >>> ['', 'asdf', 'login.php']

path_array.remove('') 
ind = path_array.index(last_element) 
new_path = '/' + '/'.join(path_array[:ind+1]) + '/'

# making SplitResult() object with edited data:
new_url = SplitResult(scheme=split_url.scheme, netloc=split_url.netloc, path=new_path, query='', fragment='')

# unsplitting:
base_url = urlunsplit(new_url)

同意这样做的最佳方式是

具体来说,您可以使用分解url,然后用空字符串替换除
scheme
netloc
之外的所有属性。如果您想保留
path
属性(如您的问题所示),可以通过额外的字符串解析步骤来实现。下面的函数示例:

import urllib.parse
def base_url(url, with_path=False):
    parsed = urllib.parse.urlparse(url)
    path   = '/'.join(parsed.path.split('/')[:-1]) if with_path else ''
    parsed = parsed._replace(path=path)
    parsed = parsed._replace(params='')
    parsed = parsed._replace(query='')
    parsed = parsed._replace(fragment='')
    return parsed.geturl()
示例:

>>> base_url('http://127.0.0.1/asdf/login.php', with_path=True)
'http://127.0.0.1/asdf'
>>> base_url('http://127.0.0.1/asdf/login.php')
'http://127.0.0.1'

re.sub(r“[^/]*(\?*)$”,“”,x)
这可能被视为作弊,但您可以使用
os.path.dirname()。我不确定这是否适用于Windows,但它适用于Linux。@zondo:我在Windows上,它肯定适用于我(在Py 3.5.1上)。@ShadowRanger:接受我的想法是不公平的(我在乎什么?反正我投了更高的票。@zondo:事实上,我在你的评论之前发布了我的答案。:-)此后我进行了编辑,添加了一些备选方案和澄清(尽管没有显示编辑历史,奇怪),但这确实是我尝试的第一件事。我正好在Windows上,这确实有帮助,因此我可以快速确认它也在Windows上工作;否则,如果您有一个没有斜杠的字符串,您将以静默方式返回空字符串(因为
rfind
将返回-1,您将添加1,并从0切片到0)。至少使用
rindex
,你会得到一个异常,而不是继续,直到有一个空字符串导致所有东西都爆炸。你知道为什么
os.path.dirname
也能很好地处理URL吗?@dalanmiller:因为它们使用相同的分隔符。即使在Windows上,正斜杠也是合法的路径分隔符(只是Windows优先使用反斜杠),因此路径操作API设计用于处理任何地方的正斜杠,URL也以同样的方式使用正斜杠。鉴于这个问题与URL有关,我想说,
urllib.parse
应该是stdlib推荐使用的部分。。。URL以及对它们的支持可能会彼此一致地改变,而对新URL特性的支持(如果有)可能不会像以前那样添加到文件处理功能中,因为可能会变得不必要的复杂。虽然我个人仍然喜欢略显生硬的解决方案,并用几种方法整理出许多东西;)您的拆分和重新联接可能应该使用
“/”。请联接
,否则将删除所有斜杠。另一个更聪明的方法可能是
”。join(split_url.rpartition('/')[:-1]
,它只执行一次拆分,如果没有斜线,实际上就变成了一个noop。很棒的提示暗影游侠,我一直想知道你是否可以这样做,但从来没有想过要看。祝贺你的答案;)这应该是答案,关于主题和透彻的解释!
base_url = urljoin('http://127.0.0.1/asdf/', '.')
# output: http://127.0.0.1/asdf/

base_url = urljoin('http://127.0.0.1/asdf', '.')
# output: http://127.0.0.1/
from urllib.parse import urlsplit
split_url = urlsplit('http://127.0.0.1/asdf/login.php')
print(split_url)

>>> SplitResult(scheme='http' netloc='127.0.0.1' path='/asdf/login.php' query='' fragment='') 
from urllib.parse import urlsplit, urlunsplit, SplitResult

# splitting url:
split_url = urlsplit('http://127.0.0.1/asdf/login.php')

# editing the variables you want to change (in this case, path):    
last_element = 'asdf'   # this can be any element in the path.
path_array = split_url.path.split('/')

# print(path_array)
# >>> ['', 'asdf', 'login.php']

path_array.remove('') 
ind = path_array.index(last_element) 
new_path = '/' + '/'.join(path_array[:ind+1]) + '/'

# making SplitResult() object with edited data:
new_url = SplitResult(scheme=split_url.scheme, netloc=split_url.netloc, path=new_path, query='', fragment='')

# unsplitting:
base_url = urlunsplit(new_url)
import urllib.parse
def base_url(url, with_path=False):
    parsed = urllib.parse.urlparse(url)
    path   = '/'.join(parsed.path.split('/')[:-1]) if with_path else ''
    parsed = parsed._replace(path=path)
    parsed = parsed._replace(params='')
    parsed = parsed._replace(query='')
    parsed = parsed._replace(fragment='')
    return parsed.geturl()
>>> base_url('http://127.0.0.1/asdf/login.php', with_path=True)
'http://127.0.0.1/asdf'
>>> base_url('http://127.0.0.1/asdf/login.php')
'http://127.0.0.1'