2010-01-30 81 views
5

我正在嘗試編寫一個工具來檢查代理服務器是否啓動並可供使用。到目前爲止,我已經在下面的類中提出了兩種方法(我刪除了對這個問題是多餘的setter和getters)。檢測代理服務器是否可用的最佳方法是什麼?

第一種方法使用cURL並嘗試通過代理請求一個頁面,第二個工具使用fsockopen並試圖打開到代理的連接。

class ProxyList { 
    /** 
    * You could set this to localhost, depending on your environment 
    * @var string The URL that the proxy validation method will use to check proxies agains 
    * @see ProxyList::validate() 
    */ 
    const VALIDATION_URL = "http://m.www.yahoo.com/robots.txt"; 
    const TIMEOUT  = 3; 

    private static $valid = array(); // Checked and valid proxies 
    private $proxies  = array(); // An array of proxies to check 

    public function validate($useCache=true) { 
     $mh  = curl_multi_init(); 
     $ch  = null; 
     $handles = array(); 
     $delay = count($this->proxies) * 10000; 
     $running = null; 
     $proxies = array(); 
     $response = null; 

     foreach ($this->proxies as $p) { 
      // Using the cache and the proxy already exists? Skip the rest of this crap 
      if ($useCache && !empty(self::$valid[$p])) { 
       $proxies[] = $p; 
       continue; 
      } 

      $ch = curl_init(); 
      curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); 
      curl_setopt($ch, CURLOPT_URL,    self::VALIDATION_URL); 
      curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, true); 
      curl_setopt($ch, CURLOPT_PROXY,   $p); 
      curl_setopt($ch, CURLOPT_NOBODY,   true); // Also sets request method to HEAD 
      curl_setopt($ch, CURLOPT_HEADER,   false); 
      curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 
      curl_setopt($ch, CURLOPT_TIMEOUT,   self::TIMEOUT); 

      curl_multi_add_handle($mh, $ch); 
      $handles[$p] = $ch; 
     } 

     // Execute the multi-handle 
     do { 
      curl_multi_exec($mh, $running); 
      usleep($delay); 
     } while ($running); 

     // Get the results of the requests 
     foreach ($handles as $proxy => $ch) { 
      $status = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); 

      // Great success 
      if ($status >= 200 && $status < 300) { 
       self::$valid[$proxy] = true; 
       $proxies[] = $proxy; 
      } 
      else { 
       self::$valid[$proxy] = false; 
      } 

      // Cleanup individual handle 
      curl_multi_remove_handle($mh, $ch); 
     } 

     // Cleanup multiple handle 
     curl_multi_close($mh); 

     return $this->proxies = $proxies; 
    } 

    public function validate2($useCache=true) { 
     $proxies = array(); 

     foreach ($this->proxies as $proxy) { 
      // Using the cache and the proxy already exists? Skip the rest of this crap 
      if ($useCache && !empty(self::$valid[$proxy])) { 
       $proxies[] = $proxy; 
       continue; 
      } 

      list($host, $post) = explode(":", $proxy); 

      if ($conn = @fsockopen($host, $post, $errno, $error, self::TIMEOUT)) { 
       self::$valid[$proxy] = true; 
       $proxies[] = $proxy; 
       fclose($conn); 
      } else { 
       self::$valid[$proxy] = false; 
      } 
     } 

     return $this->proxies = $proxies; 
    } 
} 

到目前爲止,我更喜歡cURL方法,因爲它可以讓我像fsockopen一次檢查代理的大批量並行,這是邪惡的快,而不是一個。

我還沒有做很多與代理工作,所以我很難判斷這些方法是否足以驗證代理是否可用,或者是否有更好的方法使我缺失。

+0

哇,夥計,漂亮的圖片! – 2010-01-30 09:00:54

+0

哈哈,謝謝 – 2010-01-30 09:07:01

回答

1

嗯。試圖通過代理與安全(最可能是可用的)URL建立連接,並檢查錯誤,聽起來就像o.k.對我來說。

爲了確保最大的安全性,您可能希望將另一個調用添加到另一個驗證網址(例如Google的某個網址),或者爲了以防萬一,請將其設爲兩個呼叫。

+0

第二次可用性檢查聽起來不錯,但是提出的請求越多,性能就越受關注。 – 2010-01-30 09:37:09

+0

是的。這取決於預期的用途,我猜。 – 2010-01-30 09:48:20

1

cURL是首選方法,因爲multi_exec。

我不會打擾做兩個檢查,但立即執行谷歌(或一個Proxyjudge)調用。 代理有時可以允許套接字,但只是不會獲取一個東西:因此,你的cURL方法將是安全的,而不是那麼慢。

由於上面的Pekka提到:它取決於預期用途。

您是否使用Charon並收穫了代理負載,我希望他們通過代理判斷進行檢查,並且我想知道轉換時間(以避免緩慢的代理)和anonimity。

如果你想使用它作爲企業代理的監控系統,我只想確保它可以獲取一個頁面。

a(混沌)通過使用cURL獲取URL來檢查代理的示例。

TLDR:使用cURL,它可以處理並行請求,並且最穩定而不會減慢(通過不執行doublecheck)。 http://www.oooff.com/php-affiliate-seo-blog/php-automation-coding/easy-php-proxy-checker-writing-tutorial/

相關問題