यदि कोई URL मौजूद है / तो क्या मैं जाँच कर सकता / सकती हूँ?


117

मैं विज़ुअल सी # 2005 में एक साधारण कार्यक्रम बना रहा हूं जो याहू पर स्टॉक सिंबल दिखता है! वित्त, ऐतिहासिक डेटा डाउनलोड करता है, और फिर निर्दिष्ट टिकर प्रतीक के लिए मूल्य इतिहास को प्लॉट करता है।

मुझे सटीक URL पता है कि मुझे डेटा प्राप्त करने की आवश्यकता है, और यदि उपयोगकर्ता मौजूदा टिकर प्रतीक (या याहू! वित्त पर डेटा का कम से कम एक डेटा) इनपुट करता है तो यह पूरी तरह से ठीक काम करता है। हालाँकि, मेरे पास एक रन-टाइम त्रुटि है यदि उपयोगकर्ता टिकर प्रतीक बनाता है, क्योंकि प्रोग्राम एक गैर-मौजूद वेब पेज से डेटा खींचने की कोशिश करता है।

मैं WebClient वर्ग का उपयोग कर रहा हूं, और DownloadString फ़ंक्शन का उपयोग कर रहा हूं। मैंने WebClient वर्ग के अन्य सभी सदस्य कार्यों के माध्यम से देखा, लेकिन ऐसा कुछ भी नहीं देखा जो मैं किसी URL का परीक्षण करने के लिए उपयोग कर सकता था।

मैं यह कैसे कर सकता हूँ?


1
2.0 (VS2005) उपयोग सी # दिखाने के लिए अद्यतन
मार्क Gravell

जवाबों:


110

आप "GET" के बजाय "HEAD" अनुरोध जारी कर सकते हैं ?

(संपादित करें) - योग्य! लगता है कि मैंने पहले भी ऐसा किया है ! री-गार्नरिंग के आरोपों से बचने के लिए विकी में बदल गया। तो सामग्री डाउनलोड करने की लागत के बिना एक URL का परीक्षण करने के लिए:

// using MyClient from linked post
using(var client = new MyClient()) {
    client.HeadOnly = true;
    // fine, no content downloaded
    string s1 = client.DownloadString("http://google.com");
    // throws 404
    string s2 = client.DownloadString("http://google.com/silly");
}

क्या तुम करोगी try/ catchचारों ओर DownloadStringत्रुटियों की जांच करने के लिए; कोई ग़लती नहीं? वह मौजूद है...


C # 2.0 (VS2005) के साथ:

private bool headOnly;
public bool HeadOnly {
    get {return headOnly;}
    set {headOnly = value;}
}

तथा

using(WebClient client = new MyClient())
{
    // code as before
}

FWIW - निश्चित नहीं है कि यदि आप समस्या को हल करते हैं (शायद अलग-अलग व्यवहार क्लाइंट पक्ष के अलावा) क्योंकि आप बस HTTP विधि बदल रहे हैं। सर्वर से प्रतिक्रिया इस बात पर बहुत निर्भर करेगी कि तर्क को कैसे कोडित किया जाता है और स्टॉक मूल्य जैसी गतिशील सेवा के लिए अच्छी तरह से काम नहीं कर सकता है। स्थिर संसाधनों (उदाहरण के लिए चित्र, फ़ाइलें आदि) के लिए HEAD आमतौर पर विज्ञापित के रूप में काम करता है क्योंकि यह सर्वर में बेक किया जाता है। कई प्रोग्रामर स्पष्ट रूप से HEAD अनुरोध नहीं करते हैं क्योंकि ध्यान आमतौर पर POST और GET पर है। YMMV
डेविड टेलर

जवाब लेने के लिए इतना समय लेने के लिए क्षमा करें ... मैं स्कूल और काम से अलग हो गया और इस पोस्ट के बारे में भूल गया। एक विचार के रूप में, मैं आपके समाधान के लिए काम नहीं कर सका क्योंकि मैं विजुअल स्टूडियो 2005 का उपयोग कर रहा हूं जिसमें 'var' प्रकार नहीं है। मैंने महीनों में इस परियोजना पर काम नहीं किया है, लेकिन क्या इस तथ्य के लिए कोई सरल समाधान है? इसके अलावा जब मैंने आपके समाधान को लागू करने का प्रयास किया, तो मुझे याद है कि हेडऑनली संपत्ति को 'गेट' और 'सेट' परिभाषाओं में किसी भी कोड के साथ परिभाषित करने की कोशिश करने के लिए यह मुझ पर पागल हो गया। या शायद मैं कुछ गलत कर रहा था। फ़िर भी सहायता के लिए धन्यवाद!
डैनियल वालट्रिप

MyClient क्या है ?
किनिकेत

@Kiquenet वहाँ शरीर में एक कड़ी है, यहाँ के लिए: stackoverflow.com/questions/153451/...
मार्क Gravell

136

यहाँ इस समाधान का एक और कार्यान्वयन है:

using System.Net;

///
/// Checks the file exists or not.
///
/// The URL of the remote file.
/// True : If the file exits, False if file not exists
private bool RemoteFileExists(string url)
{
    try
    {
        //Creating the HttpWebRequest
        HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
        //Setting the Request method HEAD, you can also use GET too.
        request.Method = "HEAD";
        //Getting the Web Response.
        HttpWebResponse response = request.GetResponse() as HttpWebResponse;
        //Returns TRUE if the Status code == 200
        response.Close();
        return (response.StatusCode == HttpStatusCode.OK);
    }
    catch
    {
        //Any exception will returns false.
        return false;
    }
}

प्रेषक: http : //www.dotnetन्नाts.net.net/10/10/14/how-to-check-remote-file-exists-s-/


2
मैं इस कोड का उपयोग यह जांचने के लिए कर रहा हूं कि क्या छवियों का एक गुच्छा मौजूद है, और यह काफी धीमा है (प्रति सेकंड कुछ सेकंड)। किसी को पता है कि क्या यह इस कोड के साथ एक मुद्दा है, या इस तरह के कॉल करते समय जीवन का एक तथ्य है?
15

@ssmith एक तरीका है कि आप अपने कोड को गति दे सकते हैं यदि आप अभी तक कोशिश नहीं की थी, तो Parallel.Foreach लूप में चेक करना है। इसने मेरे url परीक्षण एप्लिकेशन को बहुत तेजी से बनाया है।
जैक फेयरफील्ड

3
यह सामान बदले में DisposedObject फेंकता है (response.StatusCode == HttpStatusCode.Oode); रैप इन
यूज़

1
उपरोक्त कोड के साथ एक समस्या है। यदि आप प्रतिक्रिया करते हैं। क्लोज़ (); तब आप प्रतिक्रिया के लिए जाँच नहीं कर सकते। सत्तुसकोड यह बंद होने के साथ ही इसे एक अपवाद फेंक देगा।
नव

@ किसी भी विधि बहुत तेजी से?
किनिकेत

36

ये समाधान बहुत अच्छे हैं, लेकिन वे भूल रहे हैं कि 200 ओके की तुलना में अन्य स्थिति कोड हो सकते हैं। यह एक समाधान है जो मैंने स्थिति की निगरानी और इस तरह के उत्पादन वातावरण पर उपयोग किया है।

यदि लक्ष्य पृष्ठ पर एक url पुनर्निर्देशित या कोई अन्य शर्त है, तो इस पद्धति का उपयोग करके रिटर्न सही होगा। इसके अलावा, GetResponse () एक अपवाद को फेंक देगा और इसलिए आपको इसके लिए एक StatusCode नहीं मिलेगा। आपको अपवाद को फंसाने और एक प्रोटोकॉलइर्र के लिए जांच करने की आवश्यकता है।

कोई भी 400 या 500 स्टेटस कोड गलत वापस आएगा। बाकी सब सच लौटे। विशिष्ट स्थिति कोड के लिए आपकी आवश्यकताओं के अनुरूप इस कोड को आसानी से संशोधित किया जाता है।

/// <summary>
/// This method will check a url to see that it does not return server or protocol errors
/// </summary>
/// <param name="url">The path to check</param>
/// <returns></returns>
public bool UrlIsValid(string url)
{
    try
    {
        HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;
        request.Timeout = 5000; //set the timeout to 5 seconds to keep the user from waiting too long for the page to load
        request.Method = "HEAD"; //Get only the header information -- no need to download any content

        using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
        {
            int statusCode = (int)response.StatusCode;
            if (statusCode >= 100 && statusCode < 400) //Good requests
            {
                return true;
            }
            else if (statusCode >= 500 && statusCode <= 510) //Server Errors
            {
                //log.Warn(String.Format("The remote server has thrown an internal error. Url is not valid: {0}", url));
                Debug.WriteLine(String.Format("The remote server has thrown an internal error. Url is not valid: {0}", url));
                return false;
            }
        }
    }
    catch (WebException ex)
    {
        if (ex.Status == WebExceptionStatus.ProtocolError) //400 errors
        {
            return false;
        }
        else
        {
            log.Warn(String.Format("Unhandled status [{0}] returned for url: {1}", ex.Status, url), ex);
        }
    }
    catch (Exception ex)
    {
        log.Error(String.Format("Could not test url {0}.", url), ex);
    }
    return false;
}

1
मुझे लगता है कि 3xx रेंज में कुछ स्टेटस कोड वास्तव में एक त्रुटि का कारण
बनेंगे

3
बस इस दृष्टिकोण के साथ एक पुल-योर-हेयर-आउट समस्या का अनुभव किया: HttpWebRequestयदि आप किसी और चीज को डाउनलोड करने का प्रयास करते हैं .Close(), तो यह पसंद नहीं responseहै। घंटों लग गए उस एक को खोजने के लिए!
jbeldock

4
HttpWebResponseऑब्जेक्ट को usingब्लॉक में संलग्न किया जाना चाहिए क्योंकि यह लागू होता है IDisposableजो कनेक्शन को बंद करना भी सुनिश्चित करेगा। इससे @jbeldock जैसी समस्याओं का सामना करना पड़ सकता है।
हबीब

2
यह एक ब्राउज़र में ठीक काम करने वाले url पर 404 Not Founds फेंक रहा है ...?
माइकल ट्रेंचिडा

@MichaelTranchida वेब सर्वर 404 के लिए कुख्यात हैं, जब आप ऐसी विधि जारी करते हैं जो समर्थित नहीं है। आपके मामले में Headउस संसाधन पर समर्थन नहीं किया Getजा सकता है, हालांकि हो सकता है। इसके बदले 405 फेंकना चाहिए था।
श्रीराम सक्तिवेल

9

यदि मैं आपके प्रश्न को सही ढंग से समझता हूं, तो आप अपने URL परीक्षण के परिणाम देने के लिए इस तरह की एक छोटी विधि का उपयोग कर सकते हैं:

WebRequest webRequest = WebRequest.Create(url);  
WebResponse webResponse;
try 
{
  webResponse = webRequest.GetResponse();
}
catch //If exception thrown then couldn't get response from address
{
  return 0;
} 
return 1;

आप एक विधि में उपरोक्त कोड को लपेट सकते हैं और सत्यापन करने के लिए इसका उपयोग कर सकते हैं। मुझे आशा है कि यह आपके द्वारा पूछे गए प्रश्न का उत्तर देगा।


1
हां, शायद आप विभिन्न मामलों (टीसीपी कनेक्शन विफलता - मेजबान मना कनेक्शन, 5xx - कुछ घातक हुआ, 404 - संसाधन नहीं मिला आदि) के बीच अंतर करके समाधान को परिष्कृत कर सकते हैं। WebException की स्थिति संपत्ति पर एक नज़र डालें;)
डेविड टेलर

बहुत अच्छी बात डेविड! इससे हमें अधिक विस्तृत प्रतिक्रिया मिलेगी, ताकि हम त्रुटि को अधिक सूक्ष्मता से संभाल सकें।
कैलेंडर सॉफ्टवेयर

1
धन्यवाद। मेरा कहना है कि इस प्याज में कई परतें हैं, जिनमें से प्रत्येक कार्य (रिब फ्रेमवर्क, डीएनएस रिज़ॉल्यूशन, टीसीपी कनेक्टिविटी, लक्ष्य वेब सर्वर, लक्ष्य एप्लिकेशन आदि) में एक रिंच फेंक सकते हैं। IMHO एक अच्छा डिज़ाइन, सूचनात्मक प्रतिक्रिया और उपयोगी निदान प्रदान करने के लिए विभिन्न विफलता स्थितियों के बीच भेदभाव करने में सक्षम होना चाहिए। आइए हम यह भी भूल जाते हैं कि HTTP के पास किसी कारण से स्थिति कोड नहीं हैं;)
डेविड टेलर

6

इसे आज़माएं (सुनिश्चित करें कि आप System.Net का उपयोग करते हैं):

public bool checkWebsite(string URL) {
   try {
      WebClient wc = new WebClient();
      string HTMLSource = wc.DownloadString(URL);
      return true;
   }
   catch (Exception) {
      return false;
   }
}

जब चेकवेबसाइट () फ़ंक्शन को कॉल किया जाता है, तो यह URL के स्रोत कोड को उसमें पारित करने की कोशिश करता है। यदि इसे स्रोत कोड मिल जाता है, तो यह सच हो जाता है। यदि नहीं, तो यह गलत है।

कोड उदाहरण:

//The checkWebsite command will return true:
bool websiteExists = this.checkWebsite("https://www.google.com");

//The checkWebsite command will return false:
bool websiteExists = this.checkWebsite("https://www.thisisnotarealwebsite.com/fakepage.html");

3

यहाँ एक और विकल्प है

public static bool UrlIsValid(string url)
{
    bool br = false;
    try {
        IPHostEntry ipHost = Dns.Resolve(url);
        br = true;
    }
    catch (SocketException se) {
        br = false;
    }
    return br;
}

3
यह जाँचने के लिए उपयोगी हो सकता है कि मेजबान मौजूद है या नहीं। यह प्रश्न स्पष्ट रूप से चिंतित नहीं है कि मेजबान मौजूद है या नहीं। यह खराब HTTP पथ को संभालने से संबंधित है जिसे देखते हुए होस्ट को अस्तित्व और ठीक होना ज्ञात है
बिंकी

3

इस समाधान का पालन करना आसान लगता है:

public static bool isValidURL(string url) {
    WebRequest webRequest = WebRequest.Create(url);
    WebResponse webResponse;
    try
    {
        webResponse = webRequest.GetResponse();
    }
    catch //If exception thrown then couldn't get response from address
    {
        return false ;
    }
    return true ;
}

1
WebResponse बंद करना न भूलें, प्रतिक्रिया समय बढ़ने पर हर बार जब आप अपने तरीके से कॉल करेंगे
Madagaga

3
WebRequest request = WebRequest.Create("http://www.google.com");
try
{
     request.GetResponse();
}
catch //If exception thrown then couldn't get response from address
{
     MessageBox.Show("The URL is incorrect");`
}

1
कृपया अपने उत्तर में कुछ स्पष्टीकरण जोड़ें। कोड-केवल उत्तर भ्रमित करने वाले होते हैं और भविष्य के पाठकों के लिए उपयोगी नहीं होते हैं और इस तरह से डाउनवोट को आकर्षित कर सकते हैं।
जेसी

2

मेरे पास मौसम का निर्धारण करने के लिए एक अधिक सरल तरीका है जो एक url मान्य है।

if (Uri.IsWellFormedUriString(uriString, UriKind.RelativeOrAbsolute))
{
   //...
}

4
नहीं, यह विधि जाँच नहीं करती है कि url वास्तव में सुलभ है या नहीं। यह तब भी सच है जब Uri.IsWellFormedUriString (" 192.168.1.421 ", ...), जो स्पष्ट रूप से गलत url का उपयोग करते हैं
zhaorufei

2

मैंने हमेशा पाया है कि अपवादों को संभालने के लिए बहुत धीमी है।

शायद एक कम गहन तरीका एक बेहतर, तेज, परिणाम देगा?

public bool IsValidUri(Uri uri)
{

    using (HttpClient Client = new HttpClient())
    {

    HttpResponseMessage result = Client.GetAsync(uri).Result;
    HttpStatusCode StatusCode = result.StatusCode;

    switch (StatusCode)
    {

        case HttpStatusCode.Accepted:
            return true;
        case HttpStatusCode.OK:
            return true;
         default:
            return false;
        }
    }
}

तो बस का उपयोग करें:

IsValidUri(new Uri("http://www.google.com/censorship_algorithm"));

1

वेब सर्वर एक HTTP स्थिति कोड के साथ जवाब देते हैं जो अनुरोध के परिणाम को दर्शाता है जैसे कि 200 (कभी-कभी 202) का मतलब है सफलता, 404 - नहीं मिला आदि ( यहाँ देखें )। मान लें कि URL का सर्वर एड्रेस हिस्सा सही है और आपको सॉकेट टाइमआउट नहीं मिल रहा है, तो अपवाद सबसे अधिक संभावना है कि आप HTTP स्थिति कोड 200 से अधिक था। मैं सुझाव दूंगा कि अपवाद के वर्ग की जाँच करें और देखें कि क्या अपवाद किया जाता है HTTP स्थिति कोड।

IIRC - प्रश्न में कॉल एक WebException या एक वंशज को फेंकता है। कक्षा नाम की जाँच करें कि कौन सी स्थिति को फंसाने के लिए कॉल को एक कोशिश ब्लॉक में लपेटें।


2
वास्तव में, 200-299 रेंज में कुछ भी मतलब है सफलता, IIRC
मार्क Gravell

मार्क, आप बिल्कुल सही हैं। मैंने जानबूझकर "क्लास ऑफ एरर" कॉन्सेप्ट (जैसे 5xx, 4xx, 3xx, 2xx इत्यादि) में जाने से परहेज किया, क्योंकि इससे कीड़े के पूरे डिब्बे खुल सकते हैं। यहां तक ​​कि मानक कोड (200, 302, 404, 500 आदि) को संभालना भी पूरी तरह से कोड को अनदेखा करने से बेहतर है।
डेविड टेलर

1

पहले से दिए गए उदाहरणों के बाद, मैं कहता हूँ, इस तरह की प्रतिक्रिया में प्रतिक्रिया को लपेटना भी सबसे अच्छा अभ्यास है

    public bool IsValidUrl(string url)
    {
         try
         {
             var request = WebRequest.Create(url);
             request.Timeout = 5000;
             request.Method = "HEAD";

             using (var response = (HttpWebResponse)request.GetResponse())
             {
                response.Close();
                return response.StatusCode == HttpStatusCode.OK;
            }
        }
        catch (Exception exception)
        { 
            return false;
        }
   }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.