Как я могу нормализовать URL-адрес в python
Я хотел бы знать, нормализую ли я URL-адрес в python.
Например, если у меня есть строка url вроде: " http://www.example.com/foo goo/bar.html"
Мне нужна библиотека в python, которая преобразует дополнительное пространство (или любой другой ненормированный символ) в правильный URL.
Ответы
Ответ 1
Посмотрите на этот модуль: werkzeug.utils. (сейчас в werkzeug.urls
)
Функция, которую вы ищете, называется "url_fix" и работает так:
>>> from werkzeug.urls import url_fix
>>> url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)')
'http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29'
Это реализовано в Werkzeug следующим образом:
import urllib
import urlparse
def url_fix(s, charset='utf-8'):
"""Sometimes you get an URL by a user that just isn't a real
URL because it contains unsafe characters like ' ' and so on. This
function can fix some of the problems in a similar way browsers
handle data entered by the user:
>>> url_fix(u'http://de.wikipedia.org/wiki/Elf (Begriffsklärung)')
'http://de.wikipedia.org/wiki/Elf%20%28Begriffskl%C3%A4rung%29'
:param charset: The target charset for the URL if the url was
given as unicode string.
"""
if isinstance(s, unicode):
s = s.encode(charset, 'ignore')
scheme, netloc, path, qs, anchor = urlparse.urlsplit(s)
path = urllib.quote(path, '/%')
qs = urllib.quote_plus(qs, ':&=')
return urlparse.urlunsplit((scheme, netloc, path, qs, anchor))
Ответ 2
Реальное исправление в Python 2.7 для этой проблемы
Правильное решение:
# percent encode url, fixing lame server errors for e.g, like space
# within url paths.
fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]")
Для получения дополнительной информации см. Issue918368: "urllib не исправляет серверные URL-адреса"
Ответ 3
используйте urllib.quote
или urllib.quote_plus
Из документации urllib:
quote (string [, safe])
Заменить специальные символы в строке используя "% xx". Буквы, цифры, а символы "_.-" - никогда не цитируется. Дополнительный сейф Параметр указывает дополнительные символы, которые не должны указываться - его значение по умолчанию: '/'.
Пример: quote('/~connolly/')
дает '/%7econnolly/'
.
quote_plus (строка [, safe])
Как и quote(), но также заменяет пробелы по знакам плюс, как это требуется для цитирования Значения HTML-формы. Плюс знаки в исходная строка сбрасывается, если только они включены в сейф. Это также не имеет безопасного по умолчанию '/'.
EDIT: использование urllib.quote или urllib.quote_plus на весь URL-адрес будет искажать его, как указывает @TΖΩΤ out:
>>> quoted_url = urllib.quote('http://www.example.com/foo goo/bar.html')
>>> quoted_url
'http%3A//www.example.com/foo%20goo/bar.html'
>>> urllib2.urlopen(quoted_url)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "c:\python25\lib\urllib2.py", line 124, in urlopen
return _opener.open(url, data)
File "c:\python25\lib\urllib2.py", line 373, in open
protocol = req.get_type()
File "c:\python25\lib\urllib2.py", line 244, in get_type
raise ValueError, "unknown url type: %s" % self.__original
ValueError: unknown url type: http%3A//www.example.com/foo%20goo/bar.html
@ΤΖΩΤΖΙΟΥ предоставляет функцию, которая использует urlparse.urlparse и urlparse.urlunparse для синтаксического анализа URL-адреса и только кодирования пути. Это может быть более полезным для вас, хотя, если вы создаете URL-адрес из известного протокола и хоста, но с подозрительным путем, вы, вероятно, могли бы сделать так же, чтобы избежать urlparse и просто указать подозрительную часть URL-адреса, объединившись с известных безопасных частей.
Ответ 4
Поскольку эта страница является лучшим результатом для поисковых запросов Google по этой теме, я думаю, стоит упомянуть о некоторой работе, выполненной по нормализации URL-адреса с Python, которая выходит за рамки символов urlencoding. Например, работа с портами по умолчанию, случай символа, отсутствие завершающих косых черт и т.д.
Когда разрабатывался формат синдикации Atom, было некоторое обсуждение того, как нормализовать URL-адреса в каноническом формате; это описано в статье PaceCanonicalIds на вики-странице Atom/Pie. В этой статье приводятся некоторые хорошие тестовые примеры.
Я считаю, что одним из результатов этого обсуждения была библиотека Mark Nottingham urlnorm.py, которую я использовал с хорошими результатами по нескольким проектам, Тем не менее, script не работает с URL, указанным в этом вопросе. Таким образом, лучшим выбором может быть версия Ruby от urlnorm.py, которая обрабатывает этот URL-адрес и все вышеупомянутые тестовые примеры из вики файла Atom.
Ответ 5
PY3
from urllib.parse import urlparse, urlunparse, quote
def myquote(url):
parts = urlparse(url)
return urlunparse(parts._replace(path=quote(parts.path)))
>>> myquote('https://www.example.com/~user/with space/index.html?a=1&b=2')
'https://www.example.com/~user/with%20space/index.html?a=1&b=2'
py2
import urlparse, urllib
def myquote(url):
parts = urlparse.urlparse(url)
return urlparse.urlunparse(parts[:2] + (urllib.quote(parts[2]),) + parts[3:])
>>> myquote('https://www.example.com/~user/with space/index.html?a=1&b=2')
'https://www.example.com/%7Euser/with%20space/index.html?a=1&b=2'
Это цитирует только компонент пути.
Ответ 6
Просто FYI, urlnorm переместился в github: http://gist.github.com/246089
Ответ 7
Действителен для Python 3.5:
import urllib.parse
urllib.parse.quote([your_url], "\./_-:")
Пример:
import urllib.parse
print(urllib.parse.quote("http://www.example.com/foo goo/bar.html", "\./_-:"))
вывод будет http://www.example.com/foo%20goo/bar.html
Шрифт: https://docs.python.org/3.5/library/urllib.parse.html?highlight=quote#urllib.parse.quote
Ответ 8
Я сталкиваюсь с такой проблемой: нужно просто указать пробел.
fullurl = quote(fullurl, safe="%/:=&?~#+!$,;'@()*[]")
Помогите, но это слишком сложно.
Итак, я использовал простой способ: url = url.replace(' ', '%20')
, он не идеален, но это самый простой способ и работает для этой ситуации.