これは、cURL への柔軟なマルチスレッド呼び出しです。 これは、PHP マニュアル http://us2.php.net/manual/zh/function.curl-multi-select.php で提供されているサンプルとは異なり、コードの実行効率がはるかに高くなります。ここには 2 つのファイルがあります。 one は 2 つのクラスを含む muti_curl のファイルです 1 つは利用可能な方法で、ここでは大量検査エージェント IP が利用可能かどうかを確認します。
- class request_setting {
- public $url = false;
- public $method = 'GET';
- public $post_data = null;
- public $headers = null;
- public $options = null;
- function __construct($url, $method = "GET", $post_data = null, $headers = null, $options = null) {
- $this->url = $url;
- $this->method = $メソッド;
- $this->post_data = $post_data;
- $this->headers = $headers;
- $this->gt;options = $options;
- }
- public function __destruct() {
- unset($this- >url, $this->メソッド, $this->post_data, $this->headers, $this->options);
- }
- }
- /*************************************************** * *******************************************
- バッチ操作用のクラス
- * ************************************************ ** ***************************************/
- class muti_curl {
- protected $thread_size = 100;
- protected $timeout = 30;
- private $callback;
- protected $options = array(
- CURLOPT_SSL_VERIFYPEER => false,// 使用を禁止した後、cURL はサービス端末からのテストを終了します。CURLOPT_CAINFO を使用します置CURLOPT_CAPATH 設定を使用してください。 CURLOPT_SSL_VERIFYPEER (承認値は 2) が使用されている場合、CURLOPT_SSL_VERIFYHOST は FALSE に設定されている必要があります。 TRUE。cURL 7.10 から承認済みのインストールが開始されます。
- CURLOPT_RETURINTRANSFER => ; true, //curl_exec() で取得した情報を直接送信するのではなく、ファイル ストリームの形式で返します
- CURLOPT_CONNECTTIMEOUT => 15、
- CURLOPT_TIMEOUT => 30,
- // CURLOPT_HTTP_VERSION=>CURL_HTTP_VERSION_1_0, // 代理店を使用するときにデータを参照し、更
- // CURLOPT_AUTOREFERER=>false,// 現在Location: 重定方向、自動設置ヘッダー中のReferer: 情報。
- // CURLOPT_BINARYTRANSFER=>false, // CURLOPT_RETURNTRANSFER を使用する場合、この不使用の設定が返されます。
- // CURLOPT_COOKIESESSION=>true,// timecurl セッションのみを使用します仅传递一个セッション cookie、他の cookie、承認状態の下の cURL はすべての cookie を返します
- // CURLOPT_CRLF=>false,// 一時的に Unix の交換行番号を交換行程に変換します。
- // CURLOPT_DNS_USE_GLOBAL_CACHE=> false, // 時間会議は完全なローカルの DNS を使用して保存され、これはインターネット上で安全であり、アプリケーションを承認します。 HTTP 情報。
- // CURLOPT_FILETIME=>true, // 使用時に変更されたプログラム内の情報が返されます。結果の情報は、curl_getinfo() 関数の CURLINFO_FILETIME オプションによって返されます。
- // CURLOPT_FOLLOWLOCATION=>false, // 一時的にサーバーが返す「Location:」の戻りサーバーは、CURLOPT_MAXREDIRS を使用して戻りの数を制限できます。本当の, // 通信が完了した後に接続を強制的に切断するため、再利用できません。
- // CURLOPT_FRESH_CONNECT=>true,// 新しい接続の取得を制限し、既存の接続を置き換えます。
- // CURLOPT_FTP_USE_EPRT=>false,// FALSE に設定すると、FTP のダウンロード時に EPRT (または LPRT) コマンドが使用され、PORT コマンドのみが使用されます。
- // CURLOPT_FTP_USE_EPSV=>false,// 使用時、FTP 転送中に PASV モードに戻る前に最初に EPSV コマンドが実行されます。FALSE に設定されている場合は EPSV コマンドを無効にします。
- // CURLOPT_FTPAPPEND=>false,// 使用時
- // CURLOPT_FTPASCII=>false,// CURLOPT_TRANSFERTEXT の名前。
- // CURLOPT_FTPLISTONLY=>false,// 一時的に FTP 項目の名前のみを出力します。
- // CURLOPT_HEADER= >true,// 使用時間は、ファイルの情報をデータ ストリームとして出力します。
- // CURLINFO_HEADER_OUT=>false, // 使用時間を追跡する句柄の要求文字列。
- // CURLOPT_HTTPGET=>true,//
- // CURLOPT_HTTPPROXYTUNNEL =>true,// アプリタイム ミーティングは HTTP のメソッドを GET に設定します。GET は承認されているため、変更された場合にのみ使用されます。 =>true,// 使用中に、cURL 関数内の変更されたすべてのパラメータが値に置き換えられます。
- // CURLOPT_NETRC=>false, // 接続の確立後、~/.netrc ファイルがユーザー名と暗号情報を取得します。 Curlopt_nobody => true、gt、启用启用时不不对对对中中部分// curlopt_noprogress => false、//
- // CURLOPT_NOSIGNAL=>false,// 一時的に、php を介して転送されるすべてのカールのシグナルを使用します。この項目は、SAPI マルチスレッド送信中にデフォルトで有効になります。 cURL 7.10 で追加されました。
- // CURLOPT_POST=>false,// 有効にすると、フォーム送信と同様に、application/x-www-form-urlencoded と入力して、通常の POST リクエストが送信されます。
- // CURLOPT_PUT=>false,// 有効にすると HTTP によるファイルの送信を許可します。CURLOPT_INFILE と CURLOPT_INFILESIZE を同時に設定する必要があります。
- // CURLOPT_TRANSFERTEXT=>false,// 有効にすると、FTP 送信に ASCII モードを使用します。 LDAP の場合、HTML ではなくプレーン テキスト情報を取得します。 Windows システムでは、システムは STDOUT をバイナリ モードに設定しません。
- // CURLOPT_UNRESTRICTED_AUTH=>true,// ドメイン名が変更された場合でも、CURLOPT_FOLLOWLOCATION を使用して生成されたヘッダー内の複数の場所にユーザー名とパスワードの情報を継続的に追加します。
- // CURLOPT_UPLOAD=>false,// 有効な場合、ファイルのアップロードを許可します。
- // CURLOPT_VERBOSE =>true,// 有効にすると、すべての情報が報告され、STDERR または指定された CURLOPT_STDERR に保存されます。
- );
- private $headers = array();
- private $requests = array();
- private $requestMap = array();
- /*********************
- コールバック関数を構築します
- ********************/
- function __construct($callback = null) {
- $this->callback = $callback;
- }
-
- /*************************************************** * ******************
- __get メソッドのオーバーロード
- ************************* *******************************************/
- public function __get($name) {
- return (isset($this->gt;{$name})) ? $this->{$name} : null;
- }
-
- /*************************************************** * *******************
- __set メソッドのオーバーロード
- ************************ * *******************************/
- public function __set($name, $value) {
- // ヘッダーに增加一设設置
- if ($name = = "オプション" || $name == "ヘッダー") {
- $this->{$name} = $value + $this->{$name};
- } else {
- $this->{ $name} = $value;
- }
- return true;
- }
- //增加一请求
- public function add($request) {
- $this->requests[] = $request;
- return true;
- }
-
-
- public function request($url, $method = "GET", $post_data = null, $headers = null, $options = null) {
- $this->requests[] = new request_setting($url, $method , $post_data, $headers, $options);
- return true;
- }
-
- public function get($url, $headers = null, $options = null) {
- return $this->request($url, " GET", null, $headers, $options);
- }
-
- public function post($url, $post_data = null, $headers = null, $options = null) {
- return $this->request($url , "POST", $post_data, $headers, $options);
- }
-
- プライベート関数 single_curl() {
- $ch =curl_init(); //初期化
- $request = array_shift($this->requests);//結果として最初の单元を移動します
- $options = $this->get_options($request);//この单元の配置を取得します
- curl_setopt_array($ch, $options);//批设置
- $output =curl_exec($ch);
- $curl_info =curl_getinfo($ch);
-
- if ($this->callback) {
- $callback = $this->callback;
- if (is_callable($this->callback)) {
- call_user_func($callback, $output, $curl_info, $request);
- }
- }
- else
- return $output;
- return true;
- }
-
-
- プライベート関数rolling_curl($thread_size = null) {
- if ($thread_size){
- $this->thread_size = $thread_size;
- }
-
- if (count($this->requests) < $this->thread_size){
- $this->thread_size = count($this->requests);
- }
- if ($this->thread_size < 2) {
- $errorinfo = '線程大小必ず 1 より大きい!!!!';
- throw new Exception($errorinfo);
- }
- $queue =curl_multi_init();
- //在線程里开始增加任务队列
- for ($i = 0; $i <; $this->スレッドサイズ; $i++) {
- $ch =curl_init();
- $options = $this->get_options($this->requests[$i]);
- curl_setopt_array($ch, $options);//获得设置
- curl_multi_add_handle($queue, $ch);// 追加去
- $key = (string) $ch;
- $this->requestMap[$key] = $i;
- }
- do {
- while (($statu_run_muti_exec = curl_multi_exec($queue, $active)) == CURLM_CALL_MULTI_PERFORM) ;
- if ($statu_run_muti_exec != CURLM_OK){ Break; }
- // 完了したリクエストを発行し、処理を実行します
- while ($done =curl_multi_info_read($queue)) {
- $curl_info =curl_getinfo($done['handle']);
- $output =curl_multi_getcontent($done[' handle']);
- $callback = $this->callback;
- if (is_callable($callback)){
- $key = (string) $done['handle'];
- $request = $this-> request[$this->requestMap[$key]];
- unset($this->requestMap[$key]);//これは销毁变量用得很帅
- call_user_func($callback, $output, $curl_info, $request);
- }
- //完了済みのリクエストに未処理のリクエストを追加
- if ($i < count($this->requests) && isset($this->requests[$ i]) && $i < count($this->requests)) {
- $ch =curl_init();
- $options = $this->get_options($this->requests[$i]);
- curl_setopt_array($ch, $options);
- curl_multi_add_handle($queue, $ch);
- $key = (string) $ch;
- $this->requestMap[$key] = $i;
- $i++;
- }
- curl_multi_remove_handle($queue, $done['handle']);
- echo "done ";
- print_r($queue);
- print_r ($done);
- }
- // このステップは非常に重要です。 a completed 、タイムアウト設定をリセットします
- //ここで重要な点は、すべてのスレッドの少なくとも 1 つのリクエストが初めて有効であることを確認することです。そうでない場合、初めてのすべてのリクエストは効果がなく、結果的に $ active になります。 =0 なので、以下は実行されません
- if ($active >0){
- curl_multi_select($queue, $this->timeout);
- }
-
- } while ($active);
- curl_multi_close($queue ) ;
- return true;
- }
- public functionexecute($thread_size = null) {
- //thread_sizeのサイズを判断する。リクエストが1つしかない場合は、シングルスレッドモードを使用する
- if (count($this->requests) ) == 1) {
- return $this->single_curl();
- } else {
- return $this->rolling_curl($thread_size);
- }
- }
- private function get_options($request) {
- $options = $this ->__get('options');
- if (ini_get('safe_mode') == 'オフ' || !ini_get('safe_mode')) {
- // $options[CURLOPT_FOLLOWLOCATION] = 1;
- // $ options[CURLOPT_MAXREDIRS] = 5;
- }
- $headers = $this->__get('headers');
-
- if ($request->options) {
- $options = $request->options + $options ;
- }
- $options[CURLOPT_URL] = $request->url;
- //以下に投稿オプションとヘッダー オプションをそれぞれ設定します
- if ($request->post_data){
- $options[CURLOPT_POST] = 1;
- $options[CURLOPT_POSTFIELDS] = $request->post_data;
- }
- if ($headers) {
- $options[CURLOPT_HEADER] = 0;
- $options[CURLOPT_HTTPHEADER] = $headers;
- }
- return $options ;
- }
-
- public function __destruct() {
- unset($this->thread_size, $this->callback, $this->options, $this->headers, $this->requests);
- }
- }
- ?>
コードをコピー
- header("content-type:text/html; charset=utf-8");
- require("muti_curl_class.php");
- set_time_limit(0);
- $sucesesnum=0;
- $good_proxy=array();
- function request_callback($response, $info, $request) {
- global $sucesesnum,$good_proxy;
- // 次の正規表現は、返された結果を選択的に表示できます
- /* if ( preg_match( "~(.*?)~i", $response, $out)) {
- $title = $out[1];
- }*/
- // echo '< ;br> ;'.$response .'
';
- echo '
';
- //応答 ($response) をチェックして、設定された文字が含まれているかどうかを確認し、含まれている場合は、エージェント成功
- if( $response !== false && substr_count($response, 'ユーザーエージェント: Baiduspider') >=1 ) {
- // $result = true;
- echo "true
";
- / / echo $request[options][10004];
- // print_r ($request->options);
- echo $request->options[CURLOPT_PROXY];
- $good_proxy[]=$request->options[CURLOPT_PROXY] ] ;
- }
- echo '
the-->'. $sucesesnum.'<---use:' - // print_r ($request);
- / / echo $request->url;
- $sucesesnum++;
- echo "
";
- }
- $params = array_merge($_GET, $_POST) // ここで渡されたプロキシ IP のアドレスを取得します
- $ result = $proxy_ip = トリム($params['ip']);
- $timeout=intval(trim($params['timeout']));
- if($timeout<3 ){$timeout=3;}
- if($timeout>300){$timeout=300;}
- $thread_size=intval(trim($params['thread_size']));
- if($thread_size<5){$thread_size =5;}
- if( $thread_size>300){$thread_size =300;}
- if($proxy_ip == '') {
- echo 'IP を入力してください!!';
- return;
- }
- $replace_arr1 = array(' ', 'qq プロキシ:'、'dn28.com'、'qqip'、'qq プロキシ'、'qq プロキシ ip'、'エージェント ip:'、'ip:'、'エージェント ip'、'"'、"'" ,'\','/',' ');
- $result = str_replace($replace_arr1, array(''), $result);
- $result = str_replace(",", "n", $result);
- $resArr =explode("n", $result);
- foreach($resArr as $k => $v) {
- $posProxy = getPos($v, '@');
- if($posProxy== =false){
- if (!empty($v)){$proxyip_and_port = $v; }
- }else{
- $proxyip_and_port = substr($v, 0, $posProxy);
- }
- $newRes[] =trim ($proxyip_and_port);
- }
- print_r($newRes);
- //die();
- $option_setting = array(
- CURLOPT_SSL_VERIFYPEER => 0,
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_CONNECTTIMEOUT => 5,
- CURLOPT_TIMEOUT => 30,
- CURLOPT_HEADER=>false,
- CURLOPT_PROXY=>'',//ここにプロキシが設定されます
- );
- $url= 'http://www.baidu.com/robots.txt ' ;
- $btime=time();
- $rc = new muti_curl("request_callback");
- $rc->timeout = $timeout;
- $rc->thread_size = $thread_size;
- foreach ($newRes as $ v) {
- $option_setting[CURLOPT_PROXY]=$v;
- $request = new request_setting($url, $method = "GET", $post_data = null,$header= null, $option_setting);
- $rc-> ; add($request);
- }
- $rc->execute();
- $etime=time();
- $usedtime=$etime-$btime;
- 「すべて」をエコーします。 $ usedtime;
- echo '
';
- $good_proxy= array_unique($good_proxy);
- $str='';
- foreach ($good_proxy as $v){
- $str.="'".trim( $ v)."',";
- }
- $str= str_replace (' ' , '' ,$str );
- $str = preg_replace('/s+/', ' ', $str);
- echo $str '
';
- var_export ($good_proxy);
- //var_dump ($good_proxy);
-
-
-
-
-
-
-
-
-
-
- //********* *********************************************** **** *************************************
- //****** **** *********************使用する関数は 1 つだけです
-
- function parseProxyInfo ( $proxyStr ) {
- //$proxyStr = '202.115.207.25: 80@HTTP; 四川省成都の四川師範大学';
- $posIp = getPos($proxyStr, ':');
- $ip = substr($proxyStr, 0, $posIp);
- $posPort = getPos($ proxyStr, '@' );
- $port = substr($proxyStr, $posIp+1, $posPort-$posIp-1);
- $posType = getPos($proxyStr, ';');
- $type = substr( $proxyStr, $posPort +1, $posType-$posPort-1);
- $location = substr(strstr($proxyStr, ';'), 1);
- return array(
- 'ip' => $ip,
- 'port' = > $port,
- 'type' => $type,
- 'location' => $location
- );
- }
-
- function getPos($haystack, $needle){
- return strpos( $干し草の山、$針 );
- }
-
- function check_proxy_is_useful($model, $proxy_info_arr = array()) {
- global $params, $config;
- if($model == 'single') {
- $proxy_port = intval(trim($params['port' ]));
- $check_proxy_url = $config['verify_url'];
- $proxy_time_out = intval(trim($params['timeout']));
- $retry = intval(trim($params['retry']) );
- $proxy_ip = trim($params['ip']);
- $proxy = new proxy( $proxy_ip, $proxy_port, $check_proxy_url, $proxy_time_out, $retry );
- //成功した文字列の戻り成功、失敗した戻り値ブール値 false
- $result = $proxy -> check_proxy();
- //var_dump($result);
- $proxy_str_success = ''.$proxy_ip.':'.$proxy_port.'@'.'HTTP プロキシ验证成功! ';
- $proxy_str_failed = ''.$proxy_ip.':'.$proxy_port.'@'.'HTTP プロキシ验证失败!' ;
- $result を返す !== false ? $proxy_str_success : $proxy_str_failed;
- } elseif ($model == 'collect') {
- $proxy_port = intval(trim($proxy_info_arr['port']));
- $check_proxy_url = $config['verify_url'];
- $proxy_time_out = intval(trim ($params['timeout']));
- $retry = intval(trim($params['retry']));
- $proxy_ip = トリム($proxy_info_arr['ip']);
- /*echo $proxy_ip .'
';
- echo $proxy_port.'
';
- echo $check_proxy_url.'
';
- echo $proxy_time_out.'
';
- echo $retry.'
';*/
- if(!isset($proxy)) {
- $proxy = 新しいプロキシ( $proxy_ip, $proxy_port, $check_proxy_url, $proxy_time_out, $retry );
- }
- //成功はstring成功を返し、失敗はboolean falseを返します
- $result = $proxy -> check_proxy();
- return $result;
- }
- }
-
- function get_single(){
- global $params, $config;
- $proxy_ip = トリム($params['ip']);
- if($proxy_ip == '') {
- echo '请输入IP!!';
- return;
- }
- echo check_proxy_is_useful('single');
- }
-
- function get_proxy_by_collect(){
- global $params, $config;
- $params[' url'] = トリム($params['url']);
- if($params['url'] == '') {
- echo '请输入url!';
- return;
- }
- //$url = 'http://www.dn28.com/html/75/n-5175.html';
- $con = iconv('GBK', 'UTF-8', file_get_contents($params['url'])) ;
- preg_match ('/
|