Проблемы с анализом URL-адреса с помощью Python
Мне нужно разобрать URL. В настоящее время я использую urlparse.urlparse() и urlparse.urlsplit().
Проблема в том, что я не могу получить "netloc" (хост) из URL-адреса, когда он не представляет схему.
Я имею в виду, если у меня есть следующий URL-адрес:
www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/ref=sr_1_1?ie=UTF8&qid=1308060974&sr=8-1
Я не могу получить netloc: www.amazon.com
В соответствии с документами python:
Следуя спецификациям синтаксиса в RFC 1808, urlparse распознает netloc только если оно правильно введено "//. В противном случае предполагается, что вход быть относительным URL-адресом и, таким образом, начинать с компонентом пути.
Итак, это так нарочно. Но я все еще не знаю, как получить netloc с этого URL.
Я думаю, что могу проверить, присутствует ли схема, а если нет, добавьте ее и затем проанализируйте. Но это решение кажется не очень хорошим.
У вас есть идея?
EDIT:
Спасибо за ответы на все вопросы. Но я не могу сделать "startswith" вещь, предложенную Кори и другими. Если я получаю URL-адрес с другим протоколом/схемой, я бы испортил его. См:
Если я получаю этот URL-адрес:
ftp://something.com
С предлагаемым кодом я добавлю "http://" в начало и испортил бы его.
Решение, которое я нашел
if not urlparse.urlparse(url).scheme:
url = "http://"+url
return urlparse.urlparse(url)
Что-то примечание:
Сначала выполняю некоторую проверку, и если никакая схема не указана, я считаю ее http://
Ответы
Ответ 1
Документация имеет этот точный пример, чуть ниже вложенного текста. Добавляя '//', если он не получит то, что вы хотите. Если вы не знаете, будет ли он иметь протокол и "//", вы можете использовать регулярное выражение (или даже просто посмотреть, содержит ли оно уже "//" ), чтобы определить, нужно ли его добавлять.
Другой вариант - использовать split ('/') и взять первый элемент списка, который он возвращает, который будет ТОЛЬКО работать, когда у url нет протокола или "//'.
EDIT (добавление для будущих читателей): регулярное выражение для обнаружения протокола будет чем-то вроде re.match('(?:http|ftp|https)://', url)
Ответ 2
похоже, что вам нужно указать протокол для получения netloc.
добавление его, если оно отсутствует, может выглядеть так:
import urlparse
url = 'www.amazon.com/Programming-Python-Mark-Lutz'
if '//' not in url:
url = '%s%s' % ('http://', url)
p = urlparse.urlparse(url)
print p.netloc
Ответ 3
Из документов:
Следуя спецификациям синтаксиса в RFC 1808, urlparse распознает netloc только в том случае, если он правильно введен с помощью //. В противном случае вход считается относительным URL-адресом и, следовательно, начинается с компонента пути.
Итак, вы можете просто сделать:
In [1]: from urlparse import urlparse
In [2]: def get_netloc(u):
...: if not u.startswith('http'):
...: u = '//' + u
...: return urlparse(u).netloc
...:
In [3]: get_netloc('www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/ref=sr_1_1?ie=UTF8&qid=1308060974&sr=8-1')
Out[3]: 'www.amazon.com'
In [4]: get_netloc('http://www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/ref=sr_1_1?ie=UTF8&qid=1308060974&sr=8-1')
Out[4]: 'www.amazon.com'
In [5]: get_netloc('https://www.amazon.com/Programming-Python-Mark-Lutz/dp/0596158106/ref=sr_1_1?ie=UTF8&qid=1308060974&sr=8-1')
Out[5]: 'www.amazon.com'
Ответ 4
Если протокол всегда http, вы можете использовать только одну строку:
return "http://" + url.split("://")[-1]
Лучшим вариантом является использовать протокол, если он пошагово:
return url if "://" in url else "http://" + url
Ответ 5
Вы считали, что просто проверяете наличие "http://" в начале URL-адреса и добавляете его, если он не существует? Другое решение, предполагая, что первая часть действительно является netloc, а не частью относительного URL, состоит в том, чтобы просто захватить все до первого "/" и использовать это как netloc.
Ответ 6
Этот один вкладыш сделает это.
netloc = urlparse('//' + ''.join(urlparse(url)[1:])).netloc