পাইথন - পাইথনে ইউআরএলকে কীভাবে বৈধতা দেওয়া যায়? (ত্রুটিযুক্ত বা না)


115

আমি urlব্যবহারকারীর কাছ থেকে পেয়েছি এবং আনার এইচটিএমএল দিয়ে আমার জবাব দিতে হবে।

আমি কীভাবে ইউআরএলটির ত্রুটিযুক্ত হতে পারি তা চেক করতে পারি?

উদাহরণ স্বরূপ :

url='google'  // Malformed
url='google.com'  // Malformed
url='http://google.com'  // Valid
url='http://google'   // Malformed

আমরা কীভাবে এটি অর্জন করতে পারি?



1
কেবল এটি পড়ার চেষ্টা করুন, উদাহরণস্বরূপ যদি httplib একটি ব্যতিক্রম ছুঁড়ে ফেলে তবে আপনি জানতে পারবেন এটি অবৈধ। সমস্ত সুগঠিত ইউআরএলগুলি বৈধ নয় !
কার্পেট

1
: এই আপনাকে সাহায্য করবে stackoverflow.com/questions/827557/...
DhruvPathak

10
url='http://google' বিকৃত নয় is স্কিমা + হোস্টনাম সর্বদা বৈধ।
ভিক্টর জোরাস

উত্তর:


90

জ্যাঙ্গো ইউআরএল বৈধতা পুনরায় ( উত্স ):

import re
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? নাকি আমার কোনও পুরানো জ্যাঙ্গো সংস্করণ আছে?
রাগ্গেরো তুরা

2
@ ইউগাল-জিন্ডাল সিডটোমেন কোনও বৈধ url নয়। সংগ্রহশালাটি কারণ .museum একটি শীর্ষ-স্তরের ডোমেন (আইসিএনএএন [1] সেগুলি সংজ্ঞায়িত করে), এবং সিটোমেন নয়। [1] আইকানআর.আরজি
glarrain



2
এটি আইপিভি 6 ইউআরএলগুলির পক্ষে কাজ করবে না, যা ফর্মটি রয়েছেhttp://[2001:0DB8::3]:8080/index.php?valid=true#result
সিমনাইন

124

আসলে, আমি মনে করি এটি সবচেয়ে ভাল উপায়।

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 টি উপস্থিত রয়েছে তা যাচাই করবে, অন্যথায় এটি সঠিকভাবে গঠিত কিনা তা খতিয়ে দেখবে।

সম্পাদনা: হ্যাঁ, এই প্রশ্নটি এর সদৃশ: জ্যাঙ্গোর ভ্যালিডিটারের সাথে কোনও URL উপস্থিত আছে কিনা তা আমি কীভাবে পরীক্ষা করতে পারি?


46
তবে এটি কেবল জাঙ্গো পরিবেশে কাজ করবে অন্যথায় নয়।
যুগাল জিন্দল

19
verify_existsঅবচয় করা হয়। -1
g33kz0r

2
যুক্ত করুন: django.conf থেকে আমদানি সেটিংস সেটিংস। কনফিগার (ডিইবিইউজি = মিথ্যা) থেকে এবং যাজানো 1.5 এর সাথে কাজ চালিয়ে যাওয়ার জন্য যাচাইকরণের তালিকা সরিয়ে ফেলুন
ডিউক্যাটকডিং

1
@ যুগল জিন্দল সঠিক, তবে জ্যাঙ্গো থেকে এড়ানো প্রায় তুচ্ছ: ডি। সুতরাং, আমি এই পদ্ধতিটি ব্যবহার করি
সোদেব

7
দ্রষ্টব্য, জাঙ্গো> = 1.5 এর সাথে verify_existsআর কিছুই নেই। valভেরিয়েবলের পরিবর্তে আপনি এটিকে কল করতে পারেনURLValidator()('http://www.google.com')
लकডায়োডোনাল্ড

122

বৈধতা প্যাকেজ ব্যবহার করুন :

>>> 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 install validators) সহ ইনস্টল করুন ।


5
এটি ফাইল ইউআরএলগুলির জন্য ত্রুটি ফেলবে। : "///Users/file.txt ফাইল" এর মতো
Devavrata

2
লোকালহোস্ট url- এর জন্য ব্যর্থ validators.url("http://localhost:8080") ValidationFailure(func=url, args={'public': False, 'value': 'http://localhost:8080'})
টম

5
@ লাল জাডা, আপনি এর আগে কিছু দাবি করার আগে কিছুটা চেষ্টা করুন এবং কোডটি পরীক্ষা করুন, রিজেইক্সপ্স আসলে বেশ ভাল: ভ্যালিডেটর.ড্রেডহেডসস.আইও
ড্র্যাচেনফেলস

1
প্যাকেজের বৈধকরণের fn এর অনেকগুলি স্বেচ্ছাচারিতা সীমাবদ্ধতা রয়েছে, সুতরাং এটি সাধারণ সমাধান হিসাবে পরামর্শ দেওয়ার জন্য এটি একটি ভয়ানক পরামর্শ।
ইভান_পোজদেদেভ

2
@ আইভান_পোজদেদেভ: যদি এটি ভয়ঙ্কর হয় তবে তার থেকে আরও ভাল সমাধানের পরামর্শ দিন
জবা

62

@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
False
False
False

7
আমি জানতাম না যে আপনি অ-নয় উপাদানগুলির তালিকার সাথে যদি একটি বিবৃতি পরীক্ষা করতে পারেন। এটা সহায়ক। এছাড়াও অন্তর্নির্মিত মডিউলটি ব্যবহারের জন্য +1
মার্ক ম্যাক্সমিস্টার

9
এটি সবকিছুর অনুমতি দেয়। এটি Trueস্ট্রিং fakeবা এমনকি একটি ফাঁকা স্ট্রিংয়ের জন্য ফিরে আসে । কোনও ত্রুটি হবে না কারণ এই বৈশিষ্ট্যগুলি সর্বদা থাকে এবং তালিকার সর্বদা সত্যের বুলিয়ান মান থাকবে কারণ এতে এই বৈশিষ্ট্যগুলি রয়েছে। এমনকি সমস্ত গুণাবলীর কিছুই না থাকলেও তালিকাটি শূন্য নয়। আপনার গুণাবলির কিছুটা বৈধতা দরকার কারণ আপনার এখন যা আছে তেমন সবকিছুই পাস করে।
জন্ডো

3
মিথ্যা অবজেক্টগুলির তালিকা সত্যকে মূল্যায়ন করে: print("I am true") if [False, None, 0, '', [], {}] else print("I am false.")"আমি সত্য" "প্রিন্ট করে। যখন আমি এটি চালান। [result.scheme, result.netloc, result.path]সর্বদা মূল্যায়ন Trueprint("I am True") if [] else print("I am False.")মুদ্রণ "আমি ভুয়া।" সুতরাং খালি তালিকা মিথ্যা। অ্যারের সামগ্রীর allফাংশনের মতো কিছু নিয়ে মূল্যায়ন প্রয়োজন ।
dmmfll

3
আপনার কেন এমন পথের প্রয়োজন হবে তা নিশ্চিত নয়। আপনি result.pathপরীক্ষা থেকে অপসারণ করা উচিত ।
জেরিনো

1
এটা আমার জন্য যথেষ্ট ভাল, ধন্যবাদ। আমি কেবল এর জন্য একটি সাধারণ বৈধতা যুক্ত করেছি scheme: if not all([result.scheme in ["file", "http", "https"], result.netloc, result.path]):
আলেকজান্ডার ফোর্টিন

20

আজকাল পদ্মের উত্তরের উপর ভিত্তি করে আমি নিম্নলিখিতটি ব্যবহার করি:

$ 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")

আশা করি এটা সাহায্য করবে!


ডোমেনের নামটি কোনও ড্যাশ দিয়ে শুরু হওয়ার ক্ষেত্রে এটি ব্যর্থ হয়, যা বৈধ নয়। সরঞ্জামস.ইএইটিএফ.আর.এইচটিএমএল
বুর্জান লিন্ডকভিস্ট 25'19

এটি কেবলমাত্র বিশেষ ক্ষেত্রে উপাদানগুলি বিভক্ত করা ভাল যা ইউআরআই ত্রুটিযুক্ত নয় বলে পরিচিত । আমি অন্যান্য অনুরূপ উত্তরের আগে যেমন উত্তর দিয়েছি, এটি ত্রুটিযুক্ত ইউআরআইগুলিকে পছন্দ করে https://https://https://www.foo.bar
ইনজিহিরে

9

দ্রষ্টব্য - লেপলটি আর সমর্থিত নয়, দুঃখিত (আপনি এটি ব্যবহারে আপনাকে স্বাগত জানাই, এবং আমি মনে করি নীচের কোডটি কাজ করে তবে এটি আপডেট পাবে না)।

rfc 3696 http://www.faqs.org/rfcs/rfc3696.html এটি কীভাবে করবেন তা (HTTP url এবং ইমেলের জন্য) সংজ্ঞা দেয়। আমি লেপল (পার্সার লাইব্রেরি) ব্যবহার করে অজগরগুলিতে এর সুপারিশগুলি প্রয়োগ করেছি। দেখতে 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

2
ঝরঝরে, তবে এফটিপি বা এইচটিটিপিএসের কী হবে?
অ্যাডাম পার্কিন

6
আপনি কোডটি নকল করেন নি এবং সেগুলি কার্যকর করেছেন? এটি ওপেন সোর্স।
অ্যান্ড্রু কুক

1
lepl এখন লেখক দ্বারা বিরত হয় acooke.org/lepl/discontinued.html সম্পাদনা করুন: হেহ, শুধু বুঝলাম যে আপনি হয় লেখক
এমেট বাটলার

1
দ্রষ্টব্য: lepl.apps.rfc3696 পাইথন ৩.7.৪ এ কাজ করছে না
শীল

9

আমি এই পৃষ্ঠাটিতে অবতরণ করেছি যাতে স্ট্রিংগুলিকে "বৈধ" ইউআরএল হিসাবে বৈধতা দেওয়ার একটি বুদ্ধিমান উপায় বের করার চেষ্টা করছি। আমি পাইথন 3 ব্যবহার করে আমার সমাধানটি এখানে ভাগ করে দিচ্ছি। কোনও অতিরিক্ত গ্রন্থাগার প্রয়োজন।

যদি আপনি পাইথন 2 ব্যবহার করে থাকেন তবে https://docs.python.org/2/library/urlparse.html দেখুন ।

আপনি যেমন পাইথন 3 ব্যবহার করছেন তা https://docs.python.org/3.0/library/urllib.parse.html দেখুন ।

import urllib
from pprint import pprint

invalid_url = 'dkakasdkjdjakdjadjfalskdjfalk'
valid_url = 'https://stackoverflow.com'
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()))

পার্সারসাল্ট (স্কিম = '', নেটলোক = '', পাথ = 'ডাকাকসডকজডজাকডজাদজফালসডজফালক', প্যারামস = '', কোয়েরি = '', খণ্ড = '')

পার্সারসাল্ট (স্কিম = 'https', নেটলোক = 'স্ট্যাকওভারফ্লো ডটকম', পাথ = '', প্যারামস = '', কোয়েরি = '', খণ্ড = '')

'dkakasdkjdjakdjadjfalskdjfalk' স্ট্রিংয়ের কোনও স্কিম বা নেটলক নেই।

' https://stackoverflow.com ' সম্ভবত একটি বৈধ url।

এখানে আরও সংক্ষিপ্ত ফাংশন:

from urllib.parse import urlparse

min_attributes = ('scheme', 'netloc')


def is_valid(url, qualifying=min_attributes):
    tokens = urlparse(url)
    return all([getattr(tokens, qualifying_attr)
                for qualifying_attr in qualifying])

4

সম্পাদনা

@Kwame দ্বারা সরু আউট হিসাবে, কোড নিচে URL যাচাই করে এমনকি যদি .comবা .coইত্যাদি উপস্থিত না।

এছাড়াও @Blaise দ্বারা নির্দিষ্ট, মত URL গুলি https://www.google একটি কার্যকর URL এবং আপনি যদি এটা সমাধান করা বা না আলাদাভাবে চেক করার জন্য একটি DNS চেক করতে হবে।

এটি সহজ এবং কাজ করে:

সুতরাং min_attrস্ট্রিংগুলির বেসিক সেট রয়েছে যা কোনও ইউআরএল, অর্থাৎ http://অংশ এবং google.comঅংশের বৈধতা নির্ধারণের জন্য উপস্থিত থাকতে হবে ।

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()যদি এর ভিতরে থাকা সমস্ত ভেরিয়েবলগুলি সত্য হয়ে যায় তবে সত্যটি ফিরে আসে। সুতরাং result.schemeএবং result.netlocযদি উপস্থিত থাকে অর্থাৎ কিছু মান থাকে তবে ইউআরএলটি বৈধ এবং তাই প্রত্যাবর্তন করে True


ওহ, ভাল ধরা .. আমার ধারণা আমার কোডটি আবার নিতে হবে take আপনি কি পছন্দ করেন, রেগেক্স বাদে অন্য কোনও বিকল্প নেই।
পদম শেঠিয়া

https://www.googleএকটি বৈধ ইউআরএল। এটি আসলে সমাধান নাও হতে পারে তবে আপনি যদি যত্ন নেন তবে আপনাকে ডিএনএস চেক করা দরকার।
ব্লেইস

ব্যতিক্রমগুলি
গিলে ফেলে

2

ইউআরএল urllibএবং জ্যাঙ্গো-মতো রেগেক্স বৈধ করুন

জ্যাঙ্গো ইউআরএল এর বৈধতা প্রত্যাহারটি আসলে বেশ ভাল ছিল তবে আমার ব্যবহারের ক্ষেত্রে এটির জন্য কিছুটা সামান্য টুইট করতে হবে। এটি আপনার সাথে খাপ খাইয়ে নিতে নির্দ্বিধায়!

পাইথন ৩. 3.

import re
import urllib

# Check https://regex101.com/r/A326u1/5 for reference
DOMAIN_FORMAT = re.compile(
    r"(?:^(\w{1,255}):(.{1,255})@|^)" # http basic authentication [optional]
    r"(?:(?:(?=\S{0,253}(?:$|:))" # check full domain length to be less than or equal to 253 (starting after http basic auth, stopping before port)
    r"((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+" # check for at least one subdomain (maximum length per subdomain: 63 characters), dashes in between allowed
    r"(?:[a-z0-9]{1,63})))" # check for top level domain, no dashes allowed
    r"|localhost)" # accept also "localhost" only
    r"(:\d{1,5})?", # port [optional]
    re.IGNORECASE
)
SCHEME_FORMAT = re.compile(
    r"^(http|hxxp|ftp|fxp)s?$", # scheme: http(s) or ftp(s)
    re.IGNORECASE
)

def validate_url(url: str):
    url = url.strip()

    if not url:
        raise Exception("No URL specified")

    if len(url) > 2048:
        raise Exception("URL exceeds its maximum length of 2048 characters (given length={})".format(len(url)))

    result = urllib.parse.urlparse(url)
    scheme = result.scheme
    domain = result.netloc

    if not scheme:
        raise Exception("No URL scheme specified")

    if not re.fullmatch(SCHEME_FORMAT, scheme):
        raise Exception("URL scheme must either be http(s) or ftp(s) (given scheme={})".format(scheme))

    if not domain:
        raise Exception("No URL domain specified")

    if not re.fullmatch(DOMAIN_FORMAT, domain):
        raise Exception("URL domain malformed (domain={})".format(domain))

    return url

ব্যাখ্যা

  • কোডটি কোনও প্রদত্ত ইউআরএল schemeএবং এর netlocঅংশটি বৈধ করে । (এটি সঠিকভাবে করার জন্য, আমি urllib.parse.urlparse()দুটি যথাযথ অংশে URL টি বিভক্ত করেছিলাম যা পরে সম্পর্কিত রেজেক্স শর্তগুলির সাথে মিলে যায়))
  • netlocঅংশ স্ল্যাশ প্রথম সংঘটন আগে স্টপ /, তাই portসংখ্যার এখনও অংশ netloc, যেমন:

    https://www.google.com:80/search?q=python
    ^^^^^   ^^^^^^^^^^^^^^^^^
      |             |      
      |             +-- netloc (aka "domain" in my code)
      +-- scheme
  • IPv4 ঠিকানাগুলিও বৈধ valid

আইপিভি 6 সমর্থন

আপনি যদি চান যে ইউআরএল শনাক্তকারী IPv6 ঠিকানার সাথেও কাজ করতে পারে তবে নিম্নলিখিতগুলি করুন:

উদাহরণ

কর্মে netloc(ওরফে domain) অংশের জন্য রেজেেক্সের কয়েকটি উদাহরণ এখানে রয়েছে :


1

উপরের সমস্ত সমাধান "বৈধ হিসাবে " http://www.google.com/path,www.yahoo.com/path "এর মতো স্ট্রিংকে স্বীকৃতি দেয় । এই সমাধানটি সর্বদা এটির মতো কাজ করে

import re

# URL-link validation
ip_middle_octet = u"(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5]))"
ip_last_octet = u"(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))"

URL_PATTERN = re.compile(
                        u"^"
                        # protocol identifier
                        u"(?:(?:https?|ftp|rtsp|rtp|mmp)://)"
                        # user:pass authentication
                        u"(?:\S+(?::\S*)?@)?"
                        u"(?:"
                        u"(?P<private_ip>"
                        # IP address exclusion
                        # private & local networks
                        u"(?:localhost)|"
                        u"(?:(?:10|127)" + ip_middle_octet + u"{2}" + ip_last_octet + u")|"
                        u"(?:(?:169\.254|192\.168)" + ip_middle_octet + ip_last_octet + u")|"
                        u"(?:172\.(?:1[6-9]|2\d|3[0-1])" + ip_middle_octet + ip_last_octet + u"))"
                        u"|"
                        # IP address dotted notation octets
                        # excludes loopback network 0.0.0.0
                        # excludes reserved space >= 224.0.0.0
                        # excludes network & broadcast addresses
                        # (first & last IP address of each class)
                        u"(?P<public_ip>"
                        u"(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])"
                        u"" + ip_middle_octet + u"{2}"
                        u"" + ip_last_octet + u")"
                        u"|"
                        # host name
                        u"(?:(?:[a-z\u00a1-\uffff0-9_-]-?)*[a-z\u00a1-\uffff0-9_-]+)"
                        # domain name
                        u"(?:\.(?:[a-z\u00a1-\uffff0-9_-]-?)*[a-z\u00a1-\uffff0-9_-]+)*"
                        # TLD identifier
                        u"(?:\.(?:[a-z\u00a1-\uffff]{2,}))"
                        u")"
                        # port number
                        u"(?::\d{2,5})?"
                        # resource path
                        u"(?:/\S*)?"
                        # query string
                        u"(?:\?\S*)?"
                        u"$",
                        re.UNICODE | re.IGNORECASE
                       )
def url_validate(url):   
    """ URL string validation
    """                                                                                                                                                      
    return re.compile(URL_PATTERN).match(url)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.