Есть ли более быстрый способ проверить, существует ли внешняя веб-страница?
Я написал этот метод, чтобы проверить, существует ли страница или нет:
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 секунд. Есть ли более быстрый или эффективный способ сделать это?
Ответы
Ответ 1
Я думаю, что ваш подход довольно хорош, но изменил бы его на загрузку заголовков, добавив w.Method = WebRequestMethods.Http.Head;
перед вызовом GetResponse
.
Это может сделать это:
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;
Возможно, вам захочется также проверить другие коды состояния.
Ответ 2
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) могут ничего не возвращать из запроса главы. Я знаю, потому что сейчас я работаю над этим.
EDIT - я знаю, что есть лучшие способы проверить возвращаемые данные, чем подсчет заголовков, но это копия/вставка из материала, где это важно для нас.
Ответ 3
Одно очевидное ускорение заключается в том, чтобы запускать несколько запросов параллельно - большая часть времени будет потрачена на IO, поэтому размножение 10 потоков для каждой проверки страницы завершит всю итерацию примерно в 10 раз быстрее.
Ответ 4
- Вы можете сделать это, используя асинхронный путь, потому что теперь вы ожидаете результатов после каждого запроса. Для нескольких страниц вы можете просто бросить свою функцию в ThreadPool и дождаться завершения всех запросов. Для получения дополнительных запросов вы можете использовать асинхронные методы для ResponseStream() (BeginRead и т.д.).
- Другая вещь, которая может вам помочь (помогите мне точно) - очистить свойство
.Proxy
:
w.Proxy = null;
Без этого, по крайней мере, 1-й запрос намного медленнее, по крайней мере на моей машине.
3. Вы не можете загрузить целую страницу, но загружать только заголовок, установив параметр .Method на "HEAD".
Ответ 5
Я просто использовал ответ Фредрика Мёрка выше, но поместил его в метод:
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;
}