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