C# 有没有更快的方法检查外部网页是否存在?

C# 有没有更快的方法检查外部网页是否存在?,c#,asp.net,C#,Asp.net,我编写此方法是为了检查页面是否存在: protected bool PageExists(string url) { try { Uri u = new Uri(url); WebRequest w = WebRequest.Create(u); w.Method = WebRequestMethods.Http.Head; using (StreamReader s = new StreamReader(w.G

我编写此方法是为了检查页面是否存在:

protected bool PageExists(string url)
{
try
    {
        Uri u = new Uri(url);
        WebRequest w = WebRequest.Create(u);

            w.Method = WebRequestMethods.Http.Head;

        using (StreamReader s = new StreamReader(w.GetResponse().GetResponseStream()))
        {
            return (s.ReadToEnd().Length >= 0);
        }
    }
        catch
    {
        return false;
        }
    }

我使用它来检查一组页面(从AAAA-AAAZ迭代),运行整个循环需要3到7秒。有没有更快或更有效的方法来实现这一点?

我认为您的方法相当不错,但通过添加
w.Method=WebRequestMethods.Http.HeadGetResponse
之前执行code>

这可以做到:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://www.example.com");
request.Method = WebRequestMethods.Http.Head;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
bool pageExists = response.StatusCode == HttpStatusCode.OK;

您可能还需要检查其他状态代码。

一个明显的加速是并行运行多个请求-大部分时间将花费在IO上,因此每次检查一个页面时产生10个线程将使整个迭代的完成速度加快10倍左右

static bool GetCheck(string address)
{
    try
    {
        HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
        request.Method = "GET";
        request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
        var response = request.GetResponse();
        return (response.Headers.Count > 0);
    }
    catch
    {
        return false;
    }
}
static bool HeadCheck(string address)
{
    try
    {
        HttpWebRequest request = WebRequest.Create(address) as HttpWebRequest;
        request.Method = "HEAD";
        request.CachePolicy = new RequestCachePolicy(RequestCacheLevel.NoCacheNoStore);
        var response = request.GetResponse();
        return (response.Headers.Count > 0);
    }
    catch
    {
        return false;
    }
}
注意,某些页面(例如WCF.svc文件)可能不会从head请求返回任何内容。我知道,因为我正在努力解决这个问题。
编辑-我知道有更好的方法来检查返回数据,而不是计算标题,但这是一个复制/粘贴的东西,这对我们很重要

  • 您可以使用异步方式来完成,因为现在您正在等待每个请求之后的结果。对于几个页面,您可以将函数扔到线程池中,等待所有请求完成。对于更多请求,您可以对ResponseStream()使用异步方法(BeginRead等)
  • 另一件可以帮助您的事情(请务必帮助我)是清除
    .Proxy
    属性:
  • 如果不这样做,至少在我的机器上,第一次请求的速度要慢得多。

    3.通过将.Method设置为“HEAD”,您不能下载整个页面,只能下载页眉。

    我只是使用了上面的Fredrik Mörk答案,但将其放在了一个方法中:

    private bool checkURL(string url)
            {
                bool pageExists = false;
                try
                {
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                    request.Method = WebRequestMethods.Http.Head;
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    pageExists = response.StatusCode == HttpStatusCode.OK;
                }
                catch (Exception e)
                {
                    //Do what ever you want when its no working...
                    //Response.Write( e.ToString());
                }
                return pageExists;
            }
    

    有没有办法只获取标题,然后检查200?没错。为什么只有第一个视图字节就可以读到最后呢?@Viktor:好建议;当您给出代码示例时,我正在编写代码示例:o)当前正在尝试此操作,但当我将其放入(在using语句之前添加代码行)时,每个示例都返回404异常。试图找出原因。@Fredrik-我应该检查哪些其他状态码?从spec页()中,我能看到的唯一可能适用的另一个状态是“已找到”。@Anders:我正在考虑与重定向相关的状态(例如
    HttpStatusCode.redirect
    HttpStatusCode.Moved
    ),它指示内容存在,但不在请求的URL上。根据代码的用途,您可能还想接受其他方法。哦,是的,如果您想提高效率,您可以重构为一个将“GET”或“HEAD”作为参数的方法
    private bool checkURL(string url)
            {
                bool pageExists = false;
                try
                {
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                    request.Method = WebRequestMethods.Http.Head;
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    pageExists = response.StatusCode == HttpStatusCode.OK;
                }
                catch (Exception e)
                {
                    //Do what ever you want when its no working...
                    //Response.Write( e.ToString());
                }
                return pageExists;
            }