2009-09-04 37 views
13

tôi đã viết phương pháp này để kiểm tra xem một trang tồn tại hay không:Có cách nào nhanh hơn để kiểm tra xem trang web bên ngoài có tồn tại không?

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; 
     } 
    } 

Tôi đang sử dụng nó để kiểm tra một tập hợp các trang (lặp từ AAAA-AAAZ), và phải mất từ ​​3 đến 7 giây để chạy toàn bộ vòng lặp. Có cách nào nhanh hơn hoặc hiệu quả hơn để thực hiện việc này không?

+0

Có cách nào để có được chỉ tiêu đề, và kiểm tra 200? –

Trả lời

37

Tôi nghĩ rằng cách tiếp cận của bạn khá tốt, nhưng sẽ thay đổi nó thành chỉ tải xuống tiêu đề bằng cách thêm w.Method = WebRequestMethods.Http.Head; trước khi gọi GetResponse.

Điều này có thể làm điều đó:

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; 

Bạn có thể muốn kiểm tra cho mã trạng thái khác là tốt.

+1

Chính xác. Tại sao đọc tất cả các cách để kết thúc khi chỉ xem byte đầu tiên sẽ làm. –

+5

Và kiểm tra trạng thái phản hồi. –

+0

@Viktor: đề xuất tốt; Tôi đã viết mẫu mã trong khi bạn đã cho nó: o) –

0

Một tăng tốc rõ ràng là chạy một số yêu cầu song song - hầu hết thời gian sẽ được dùng cho IO, do đó, sinh ra 10 luồng cho mỗi lần kiểm tra một trang sẽ hoàn thành toàn bộ vòng lặp nhanh hơn khoảng 10 lần.

1
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; 
    } 
} 

Hãy coi chừng, một số trang nhất định (ví dụ: tệp WCF .svc) có thể không trả lại bất kỳ điều gì từ yêu cầu head. Tôi biết vì tôi đang làm việc xung quanh điều này ngay bây giờ.
EDIT - Tôi biết có nhiều cách tốt hơn để kiểm tra dữ liệu trả về so với đếm tiêu đề, nhưng đây là bản sao/dán từ nội dung mà điều này quan trọng đối với chúng tôi.

+0

Oh yeah, và bạn có thể cấu trúc lại thành một phương thức duy nhất có "GET" hoặc "HEAD" làm tham số, nếu bạn muốn tất cả đều hiệu quả. ;) – ZombieSheep

0
  1. Bạn có thể làm điều đó bằng cách không đồng bộ, bởi vì bây giờ bạn đang đợi kết quả sau mỗi yêu cầu. Đối với vài trang, bạn có thể chỉ cần ném chức năng của bạn trong ThreadPool, và chờ cho tất cả các yêu cầu để kết thúc. Đối với nhiều yêu cầu hơn, bạn có thể sử dụng các phương thức không đồng bộ cho ResponseStream() (BeginRead, v.v.) của bạn.
  2. Một thứ khác mà có thể giúp bạn (giúp tôi cho chắc chắn) là để xóa .Proxy tài sản:
w.Proxy = null;

Nếu không có này, ít nhất là 1 yêu cầu là chậm hơn nhiều, ít nhất là trên máy tính của tôi.
3. Bạn không thể tải xuống toàn bộ trang, nhưng chỉ tải xuống tiêu đề, bằng cách đặt .Method thành "HEAD".

-2

tôi chỉ đơn giản sử dụng Fredrik Mork câu trả lời ở trên, nhưng đặt nó trong một phương pháp:

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; 
     } 
Các vấn đề liên quan