我正在尝试使用python来更改url中的主机名,并且一直在玩urlparse模块一段时间而没有找到满意的解决方案.举个例子,考虑网址:
https://www.google.dk:80/barbaz
我想用"www.foo.dk"替换"www.google.dk",所以我得到以下网址:
所以我要替换的部分是urlparse.urlsplit所指的主机名.我曾希望urlsplit的结果会让我进行更改,但结果类型ParseResult不允许我这样做.如果没有别的我当然可以通过将所有部分与+一起附加来重建新的url,但是这会给我留下一些非常丑陋的代码以及很多条件,以便在正确的位置获得"://"和":" .
Nig*_*nel 76
您可以使用urllib.parse.urlparse
功能和ParseResult._replace
方法:
>>> import urllib.parse
>>> parsed = urllib.parse.urlparse("https://www.google.dk:80/barbaz")
>>> replaced = parsed._replace(netloc="www.foo.dk:80")
>>> print(replaced)
ParseResult(scheme='https', netloc='www.foo.dk:80', path='/barbaz', params='', query='', fragment='')
Run Code Online (Sandbox Code Playgroud)
urllib.parse
是一个子类,urlparse
并且ParseResult
是一种namedtuple
方法:
返回指定元组的新实例,用新值替换指定的字段
更新:
正如@ 2rs2ts所说,在comment _replace
属性中包含一个端口号.
好消息:namedtuple
有netloc
和ParseResult
属性.坏消息:hostname
和port
不的成员hostname
,他们的动态特性,你不能这样做port
.它会抛出异常.
如果你不想分开namedtuple
,你的网址总是有一个端口号而且没有(parsed._replace(hostname="www.foo.dk")
和:
那个网址如" https:// username:password@www.google.dk:80/barbaz ")你可以做:
parsed._replace(netloc="{}:{}".format(parsed.hostname, parsed.port))
Run Code Online (Sandbox Code Playgroud)
lin*_*ndy 16
您可以充分利用urlsplit
,并urlunsplit
从Python的urlparse
:
>>> from urlparse import urlsplit, urlunsplit
>>> url = list(urlsplit('https://www.google.dk:80/barbaz'))
>>> url
['https', 'www.google.dk:80', '/barbaz', '', '']
>>> url[1] = 'www.foo.dk:80'
>>> new_url = urlunsplit(url)
>>> new_url
'https://www.foo.dk:80/barbaz'
Run Code Online (Sandbox Code Playgroud)
正如文档所述,参数传递给urlunsplit()
"可以是任何五项迭代",因此上面的代码按预期工作.
使用urlparse
和模块的urlunparse
方法urlparse
:
import urlparse
old_url = 'https://www.google.dk:80/barbaz'
url_lst = list(urlparse.urlparse(old_url))
# Now url_lst is ['https', 'www.google.dk:80', '/barbaz', '', '', '']
url_lst[1] = 'www.foo.dk:80'
# Now url_lst is ['https', 'www.foo.dk:80', '/barbaz', '', '', '']
new_url = urlparse.urlunparse(url_lst)
print(old_url)
print(new_url)
Run Code Online (Sandbox Code Playgroud)
输出:
https://www.google.dk:80/barbaz
https://www.foo.dk:80/barbaz
Run Code Online (Sandbox Code Playgroud)
小智 5
在大多数情况下,netloc 中主机的简单字符串替换也适用:
>>> p = urlparse.urlparse('https://www.google.dk:80/barbaz')
>>> p._replace(netloc=p.netloc.replace(p.hostname, 'www.foo.dk')).geturl()
'https://www.foo.dk:80/barbaz'
Run Code Online (Sandbox Code Playgroud)
如果用户名或密码偶然与主机名匹配,这将不起作用。你不能限制 str.replace 只替换最后一次出现,所以我们可以使用 split 和 join :
>>> p = urlparse.urlparse('https://www.google.dk:www.google.dk@www.google.dk:80/barbaz')
>>> new_netloc = 'www.foo.dk'.join(p.netloc.rsplit(p.hostname, 1))
>>> p._replace(netloc=new_netloc).geturl()
'https://www.google.dk:www.google.dk@www.foo.dk:80/barbaz'
Run Code Online (Sandbox Code Playgroud)
我也建议使用urlsplit
并urlunsplit
喜欢@linkyndy 的回答,但Python3
它会是:
>>> from urllib.parse import urlsplit, urlunsplit
>>> url = list(urlsplit('https://www.google.dk:80/barbaz'))
>>> url
['https', 'www.google.dk:80', '/barbaz', '', '']
>>> url[1] = 'www.foo.dk:80'
>>> new_url = urlunsplit(url)
>>> new_url
'https://www.foo.dk:80/barbaz'
Run Code Online (Sandbox Code Playgroud)