Проблемы с анализом 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