У меня есть url
от пользователя, и я должен ответить с извлеченным HTML.
Как я могу проверить, что URL-адрес неверен?
Пример:
url='google' // Malformed
url='google.com' // Malformed
url='http://google.com' // Valid
url='http://google' // Malformed
Как мы можем достичь этого?
regex = re.compile(
r'^(?:http|ftp)s?://' # http:// or https://
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|' #domain...
r'localhost|' #localhost...
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
r'(?::\d+)?' # optional port
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
print re.match(regex, "http://www.example.com") is not None # True
print re.match(regex, "example.com") is not None # False
ftp
? Или у меня старая версия Django?
url='www.google'
искажен, но соответствует этому регулярному выражению.
Собственно, я думаю, что это лучший способ.
from django.core.validators import URLValidator
from django.core.exceptions import ValidationError
val = URLValidator(verify_exists=False)
try:
val('http://www.google.com')
except ValidationError, e:
print e
Если вы установили verify_exists
в True
, он действительно проверит, существует ли URL-адрес, иначе он просто проверит, правильно ли он сформирован.
edit: ah yeah, этот вопрос является дубликатом этого: Как проверить, существует ли URL с помощью валидаторов Djangos?
Используйте validators пакет:
>>> import validators
>>> validators.url("http://google.com")
True
>>> validators.url("http://google")
ValidationFailure(func=url, args={'value': 'http://google', 'require_tld': True})
>>> if not validators.url("http://google"):
... print "not valid"
...
not valid
>>>
Установите его с помощью pip (pip install validators
).
Верная или ложная версия, основанная на ответе @DMfll:
try:
# python2
from urlparse import urlparse
except:
# python3
from urllib.parse import urlparse
a = 'http://www.cwi.nl:80/%7Eguido/Python.html'
b = '/data/Python.html'
c = 532
d = u'dkakasdkjdjakdjadjfalskdjfalk'
def uri_validator(x):
try:
result = urlparse(x)
return all([result.scheme, result.netloc, result.path])
except:
return False
print(uri_validator(a))
print(uri_validator(b))
print(uri_validator(c))
print(uri_validator(d))
дает:
True
True
False
True
note - lepl больше не поддерживается, извините (вы можете его использовать, и я думаю, что код ниже работает, но он не будет получать обновления).
rfc 3696 http://www.faqs.org/rfcs/rfc3696.html определяет, как это сделать (для http-адресов и электронной почты). Я выполнил свои рекомендации в python, используя lepl (библиотека парсеров). см. http://acooke.org/lepl/rfc3696.html
для использования:
> easy_install lepl
...
> python
...
>>> from lepl.apps.rfc3696 import HttpUrl
>>> validator = HttpUrl()
>>> validator('google')
False
>>> validator('http://google')
False
>>> validator('http://google.com')
True
Я попал на эту страницу, пытаясь найти разумный способ проверить строки как "действительные" URL. Я поделюсь здесь своим решением, используя python3. Никаких дополнительных библиотек не требуется.
Смотрите https://docs.python.org/2/library/urlparse.html, если вы используете python2.
Смотрите https://docs.python.org/3.0/library/urllib.parse.html, если вы используете python3, как и я.
import urllib
from pprint import pprint
invalid_url = 'dkakasdkjdjakdjadjfalskdjfalk'
valid_url = 'http://qaru.site/'
tokens = [urllib.parse.urlparse(url) for url in (invalid_url, valid_url)]
for token in tokens:
pprint(token)
min_attributes = ('scheme', 'netloc') # add attrs to your liking
for token in tokens:
if not all([getattr(token, attr) for attr in min_attributes]):
error = "'{url}' string has no scheme or netloc.".format(url=token.geturl())
print(error)
else:
print("'{url}' is probably a valid url.".format(url=token.geturl()))
ParseResult (схема = '', netloc = '', путь = 'dkakasdkjdjakdjadjfalskdjfalk', params = '', query = '', фрагмент = '')
ParseResult (схема = 'https', netloc = 'stackoverflow.com', путь = '', params = '', query = '', фрагмент = '')
Строка 'dkakasdkjdjakdjadjfalskdjfalk' не имеет схемы или netloc.
1, вероятно, является действительным URL.
Вот более краткая функция:
import urllib
min_attributes = ('scheme', 'netloc')
def is_valid(url, qualifying=None):
qualifying = min_attributes if qualifying is None else qualifying
token = urllib.parse.urlparse(url)
return all([getattr(token, qualifying_attr)
for qualifying_attr in qualifying])
В настоящее время я использую следующее, основываясь на ответе Padam:
$ python --version
Python 3.6.5
И вот как это выглядит:
from urllib.parse import urlparse
def is_url(url):
try:
result = urlparse(url)
return all([result.scheme, result.netloc])
except ValueError:
return False
Просто используйте is_url("http://www.asdf.com")
.
Надеюсь, поможет!
РЕДАКТИРОВАТЬ
Как указывает @Kwame, приведенный ниже код действительно проверяет URL, даже если отсутствуют
.com
или.co
т.д.@Blaise также указал, что URL-адреса, такие как https://www.google, являются действительными, и вам необходимо выполнить проверку DNS, чтобы проверить, разрешает он или нет, отдельно.
Это просто и работает:
Таким образом, min_attr
содержит базовый набор строк, которые должны присутствовать для определения действительности URL, то есть http://
part и google.com
part.
urlparse.scheme
хранит http://
и
urlparse.netloc
хранит доменное имя google.com
from urlparse import urlparse
def url_check(url):
min_attr = ('scheme' , 'netloc')
try:
result = urlparse(url)
if all([result.scheme, result.netloc]):
return True
else:
return False
except:
return False
all()
возвращает true, если все переменные внутри него возвращают true. Таким образом, если result.scheme
и result.netloc
присутствуют, т.е. имеют какое-то значение, то URL-адрес является действительным и, следовательно, возвращает True
.
url_check('https://www.google')
возвращает True
?