Php 检测代理服务器是否可用的最佳方法是什么?
我正在尝试编写一个工具来检查代理服务器是否已启动并可供使用。到目前为止,我在下面的类中提出了两个方法(我删除了对这个问题来说多余的setter和getter) 第一个方法使用Php 检测代理服务器是否可用的最佳方法是什么?,php,curl,proxy,Php,Curl,Proxy,我正在尝试编写一个工具来检查代理服务器是否已启动并可供使用。到目前为止,我在下面的类中提出了两个方法(我删除了对这个问题来说多余的setter和getter) 第一个方法使用cURL并尝试通过代理请求页面,第二个工具使用fsockopen仅尝试打开到代理的连接 class ProxyList { /** * You could set this to localhost, depending on your environment * @var string The
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;
}
}
类ProxyList{
/**
*您可以将其设置为localhost,具体取决于您的环境
*@var string代理验证方法将用于再次检查代理的URL
*@请参阅ProxyList::validate()
*/
常量验证\u URL=”http://m.www.yahoo.com/robots.txt";
常数超时=3;
私有静态$valid=array();//已检查且有效的代理
private$proxies=array();//要检查的代理数组
公共函数验证($useCache=true){
$mh=curl_multi_init();
$ch=null;
$handles=array();
$delay=count($this->proxies)*10000;
$running=null;
$proxies=array();
$response=null;
foreach($this->代理为$p){
//使用缓存和代理已经存在?跳过剩下的废话
如果($useCache&&!empty(self::$valid[$p])){
$proxies[]=$p;
继续;
}
$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);//还将请求方法设置为HEAD
curl_setopt($ch,CURLOPT_头,false);
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);
curl_setopt($ch,CURLOPT_TIMEOUT,self::TIMEOUT);
卷曲多加手柄($mh,$ch);
$handles[$p]=$ch;
}
//执行多句柄
做{
curl_multi_exec($mh,$running);
usleep(延迟);
}同时($运行);
//获取请求的结果
foreach($作为$proxy处理=>$ch){
$status=(int)curl\u getinfo($ch,CURLINFO\u HTTP\u代码);
//巨大成功
如果($status>=200&$status<300){
self::$valid[$proxy]=true;
$proxy[]=$proxy;
}
否则{
self::$valid[$proxy]=false;
}
//清理单个句柄
卷曲多个拆卸手柄($mh,$ch);
}
//清理多个句柄
卷曲多重闭合($mh);
返回$this->proxies=$proxies;
}
公共函数validate2($useCache=true){
$proxies=array();
foreach($this->代理为$proxy){
//使用缓存和代理已经存在?跳过剩下的废话
如果($useCache&&!empty(self::$valid[$proxy])){
$proxy[]=$proxy;
继续;
}
列表($host,$post)=分解(“:”,$proxy);
if($conn=@fsockopen($host,$post,$errno,$error,self::TIMEOUT)){
self::$valid[$proxy]=true;
$proxy[]=$proxy;
fclose($康涅狄格州);
}否则{
self::$valid[$proxy]=false;
}
}
返回$this->proxies=$proxies;
}
}
到目前为止,我更喜欢cURL
方法,因为它允许我并行检查大量代理,速度非常快,而不是像fsockopen
那样一次检查一个代理
我没有对代理做太多的工作,因此我很难判断这些方法是否足以验证代理是否可用,或者是否有更好的方法我缺少。Hm。尝试通过代理建立到安全(最可能可用)URL的连接,并检查错误,听起来不错
为了获得绝对最大的安全性,您可能希望向另一个验证URL添加另一个调用(例如,Google上的某个东西),或者进行两次调用,以防万一 cURL是首选的方式,因为它有多重执行功能 我不会费心做两次检查,但要立即打谷歌(或代理法官)电话。 代理有时可以允许套接字,但不能获取任何东西:因此您的cURL方法是安全的,不会太慢 正如佩卡上面提到的:这取决于预期用途 你是否使用了Charon并收集了大量代理,我想让他们对照ProxyJudger进行检查,我想知道周转时间(以避免缓慢的代理)和速度 如果您想将它用作公司代理的监控系统,我只想确保它能够获取一个页面 通过使用cURL获取URL来检查代理的(混乱的)示例 TLDR:使用cURL,它可以处理并行请求,并且是最稳定的,不会变慢(通过不执行双重检查)。
第二次可用性检查听起来是个好主意,但请求越多,性能就越令人担忧。没错。我想这取决于预期用途。