Ни urljoin
, ни posixpath.normpath
не выполняют работу должным образом . urljoin
заставляет вас присоединяться к чему-либо, и не обрабатывает абсолютные пути или чрезмерные ..
s правильно. posixpath.normpath
сворачивает несколько косых черт и удаляет завершающие косые черты, которые не должны делать URL-адреса.
Следующая функция полностью разрешает URL-адреса, корректно обрабатывая как .
s, так и ..
s в соответствии с RFC 3986 .
try:
# Python 3
from urllib.parse import urlsplit, urlunsplit
except ImportError:
# Python 2
from urlparse import urlsplit, urlunsplit
def resolve_url(url):
parts = list(urlsplit(url))
segments = parts[2].split('/')
segments = [segment + '/' for segment in segments[:-1]] + [segments[-1]]
resolved = []
for segment in segments:
if segment in ('../', '..'):
if resolved[1:]:
resolved.pop()
elif segment not in ('./', '.'):
resolved.append(segment)
parts[2] = ''.join(resolved)
return urlunsplit(parts)
Затем вы можете позвонить по полному URL следующим образом.
>>> resolve_url("http://example.com/dir/../../thing/.")
'http://example.com/thing/'
Для получения дополнительной информации о соображениях, которые необходимо учитывать при разрешении URL-адресов, см. аналогичный ответ, который я написал ранее по этому вопросу .