リモートコンテンツをキャプチャするには、以前からfile_get_content関数を使用していました。curlなどの優れた機能の存在は知っていましたが、実際に見てみると、使い方がかなり複雑であると感じました。 file_get_content ほど単純ではないし、需要も大きくないので、curl の使い方を学びませんでした。
最近まで、Web 泥棒プログラムを作成しようとしていたときに、file_get_content ではニーズを満たせないことがわかりました。リモート コンテンツを読み取る場合、file_get_content はcurl よりも使いやすい点を除けば、curl ほど優れたものではないと思います。
phpのcurlとfile_get_contentの比較
主な違い:
調べた結果、curlはFTP、FTPS、HTTP、HTTPS、GOPHER、TELNET、DICT、FILE、LDAPなどの多くのプロトコルをサポートしていることがわかりました。 file_get_content では実行できない多くのことが実行できます。 Curl は、PHP でのコンテンツのリモート取得と収集を実行できます。PHP Web バージョンの FTP アップロードとダウンロードを実装します。インターフェイス ドッキング (API) を実装し、データ転送をシミュレートします。この機能は非常に強力です。
curl の基本的な使い方をいくつか理解した後、いくつかの設定パラメータを覚えるのは少し難しいだけですが、一般的に使用されるパラメータをいくつか覚えておくだけで十分であることがわかりました。
curlを有効にする:
PHPはデフォルトではcurl関数をサポートしていないため、curlを使用したい場合は、まずphp.iniでこの関数を有効にする必要があります。つまり、;extension=の前のセミコロンを削除します。 php_curl.dll を保存し、apache/iis を再起動すると問題なく動作します。
基本構文:
$my_curl = curl_init(); //初始化一个curl对象 curl_setopt($my_curl, CURLOPT_URL, "http://www.jb51.net"); //设置你需要抓取的URL curl_setopt($my_curl,CURLOPT_RETURNTRANSFER,1); //设置是将结果保存到字符串中还是输出到屏幕上,1表示将结果保存到字符串 $str = curl_exec($curl); //执行请求 echo $str; //输出抓取的结果 curl_close($curl); //关闭url请求
最近、他の人のウェブサイトから音楽データを取得する必要があります。 file_get_contents 関数を使用しましたが、マニュアルの例に従ってタイムアウトを設定しても、ほとんどの場合機能しませんでした。
$config['context'] = stream_context_create(array('http' => array('method' => "GET",
'timeout' => 5//このタイムアウトは不安定で、動作しないことがよくあります
)
));
この時点で、サーバー接続プールを見てください。同様のエラーがたくさん見つかり、大きな頭痛の種になります:
file_get_contents(http://***): ストリームを開けませんでした...
さて私は、curl ライブラリを使用し、次の関数置換を作成しました。
curl_setopt($ch, CURLOPT_USERAGENT, _USERAGENT_);
curl_setopt( $ch, CURLOPT_REFERER,_REFERER_);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$r =curl_exec($ch);
curl_close($ ch);
return $r;
}
つまり、実際のネットワークの問題を除いて、他の問題は発生しませんでした。
これは他の人が行ったcurlとfile_get_contentsに関するテストです:
file_get_contentsがgoogle.comをクロールするのにかかる秒数:
2.31319094
2.30374217
2.21512604
2.30124092
カール使用時間:
0.68719101
0.64326
0.819831130.63956594
大きな差?あはは、私の経験から言えば、これら 2 つのツールは速度が異なるだけでなく、安定性も異なります。
ネットワーク データ キャプチャの安定性に対する要求が高い友人には、上記のcurl_file_get_contents 関数を使用することをお勧めします。安定して高速であるだけでなく、ブラウザを偽装してターゲット アドレスを偽装することもできます。
方法 1: file_get_contents を使用して get メソッドでコンテンツを取得します
<?php $url='http://www.domain.com/'; $html = file_get_contents($url); echo $html; ?>
方法 2: fopen を使用して URL を開いて、get メソッドでコンテンツを取得します
<?php $fp = fopen($url, 'r'); stream_get_meta_data($fp); while(!feof($fp)) { $result .= fgets($fp, 1024); } echo "url body: $result"; fclose($fp); ?>
方法 3: file_get_contents 関数を使用して URL を取得します投稿メソッド
<?php $data = array ('foo' => 'bar'); $data = http_build_query($data); $opts = array ( 'http' => array ( 'method' => 'POST', 'header'=> "Content-type: application/x-www-form-urlencodedrn" . "Content-Length: " . strlen($data) . "rn", 'content' => $data ) ); $context = stream_context_create($opts); $html = file_get_contents('http://localhost/e/admin/test.html', false, $context); echo $html; ?>
方法 4: fsockopen 関数を使用して URL を開き、get メソッドでヘッダーと本文を含む完全なデータを取得します
<?php function get_url ($url,$cookie=false) { $url = parse_url($url); $query = $url[path]."?".$url[query]; echo "Query:".$query; $fp = fsockopen( $url[host], $url[port]?$url[port]:80 , $errno, $errstr, 30); if (!$fp) { return false; } else { $request = "GET $query HTTP/1.1rn"; $request .= "Host: $url[host]rn"; $request .= "Connection: Closern"; if($cookie) $request.="Cookie: $cookien"; $request.="rn"; fwrite($fp,$request); while()) { $result .= @fgets($fp, 1024); } fclose($fp); return $result; } } //获取url的html部分,去掉header function GetUrlHTML($url,$cookie=false) { $rowdata = get_url($url,$cookie); if($rowdata) { $body= stristr($rowdata,"rnrn"); $body=substr($body,4,strlen($body)); return $body; } return false; } ?>
方法 5: fsockopen 関数を使用して URL を開き、次の完全なデータを取得しますヘッダーとボディを含む POST メソッド
<?php function HTTP_Post($URL,$data,$cookie, $referrer="") { // parsing the given URL $URL_Info=parse_url($URL); // Building referrer if($referrer=="") // if not given use this script as referrer $referrer="111″; // making string from $data foreach($data as $key=>$value) $values[]="$key=".urlencode($value); $data_string=implode("&",$values); // Find out which port is needed – if not given use standard (=80) if(!isset($URL_Info["port"])) $URL_Info["port"]=80; // building POST-request: $request.="POST ".$URL_Info["path"]." HTTP/1.1n"; $request.="Host: ".$URL_Info["host"]."n"; $request.="Referer: $referern"; $request.="Content-type: application/x-www-form-urlencodedn"; $request.="Content-length: ".strlen($data_string)."n"; $request.="Connection: closen"; $request.="Cookie: $cookien"; $request.="n"; $request.=$data_string."n"; $fp = fsockopen($URL_Info["host"],$URL_Info["port"]); fputs($fp, $request); while(!feof($fp)) { $result .= fgets($fp, 1024); } fclose($fp); return $result; } ?>
方法 6:curl ライブラリを使用する。curl ライブラリを使用する前に、php.ini で Curl 拡張機能がオンになっているかどうかを確認する必要がある場合があります
<?php $ch = curl_init(); $timeout = 5; curl_setopt ($ch, CURLOPT_URL, 'http://www.domain.com/'); curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout); $file_contents = curl_exec($ch); curl_close($ch); echo $file_contents; ?>
の 3 つの関数phpのcurl、fsockopen、file_get_contentsはいずれも擬似音声の収集を実現できます。 3 つの違いは何ですか? また、注意すべき点はありますか?
Zhao Yongbin:
file_get_contents() を使用して外部ファイルを呼び出すと、時間が経つとエラーが報告されやすくなります。これをcurlに変更するだけです。具体的な理由は不明ですcurlはfile_get_contents()やfsockopen()よりも効率的です。その理由は、CURLがDNS情報を自動的にキャッシュするためです(ハイライトは私が個人的にテストするためです)
Fan Jiapeng。 :
file_get_contentscurl fsockopen
は、現在要求されている環境下での選択的な操作であり、一般化はありません:
使い始めたばかり: file_get_contents
その後使用: fsockopen
最後に、現在まで、使用: カール
(远程)我个人理解到的表述如下(不对请指出,不到位请补充)
file_get_contents 需要php.ini里开启allow_url_fopen,请求http时,使用的是http_fopen_wrapper,不会keeplive.curl是可以的。
file_get_contents()单个执行效率高,返回没有头的信息。
这个是读取一般文件的时候并没有什么问题,但是在读取远程问题的时候就会出现问题。
如果是要打一个持续连接,多次请求多个页面。那么file_get_contents和fopen就会出问题。
取得的内容也可能会不对。所以做一些类似采集工作的时候,肯定就有问题了。
sock较底层,配置麻烦,不易操作。 返回完整信息。
潘少宁-腾讯:
file_get_contents 虽然可以获得某URL的内容,但不能post get啊。
curl 则可以post和get啊。还可以获得head信息
而socket则更底层。可以设置基于UDP或是TCP协议去交互
file_get_contents 和 curl 能干的,socket都能干。
socket能干的,curl 就不一定能干了
file_get_contents 更多的时候 只是去拉取数据。效率比较高 也比较简单。
赵的情况这个我也遇到过,我通过CURL设置host 就OK了。 这和网络环境有关系
<?php /** * Socket版本 * 使用方法: * $post_string = "app=socket&version=beta"; * request_by_socket('jb51.net','/restServer.php',$post_string); */ function request_by_socket($remote_server,$remote_path,$post_string,$port = 80,$timeout = 30){ $socket = fsockopen($remote_server,$port,$errno,$errstr,$timeout); if (!$socket) die("$errstr($errno)"); fwrite($socket,"POST $remote_path HTTP/1.0"); fwrite($socket,"User-Agent: Socket Example"); fwrite($socket,"HOST: $remote_server"); fwrite($socket,"Content-type: application/x-www-form-urlencoded"); fwrite($socket,"Content-length: ".strlen($post_string)+8.""); fwrite($socket,"Accept:*/*"); fwrite($socket,""); fwrite($socket,"mypost=$post_string"); fwrite($socket,""); $header = ""; while ($str = trim(fgets($socket,4096))) { $header.=$str; } $data = ""; while (!feof($socket)) { $data .= fgets($socket,4096); } return $data; } /** * Curl版本 * 使用方法: * $post_string = "app=request&version=beta"; * request_by_curl('http://jb51.net/restServer.php',$post_string); */ function request_by_curl($remote_server,$post_string){ $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$remote_server); curl_setopt($ch,CURLOPT_POSTFIELDS,'mypost='.$post_string); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); curl_setopt($ch,CURLOPT_USERAGENT,"Jimmy's CURL Example beta"); $data = curl_exec($ch); curl_close($ch); return $data; } /** * 其它版本 * 使用方法: * $post_string = "app=request&version=beta"; * request_by_other('http://jb51.net/restServer.php',$post_string); */ function request_by_other($remote_server,$post_string){ $context = array( 'http'=>array( 'method'=>'POST', 'header'=>'Content-type: application/x-www-form-urlencoded'."". 'User-Agent : Jimmy's POST Example beta'."". 'Content-length: '.strlen($post_string)+8, 'content'=>'mypost='.$post_string) ); $stream_context = stream_context_create($context); $data = file_get_contents($remote_server,FALSE,$stream_context); return $data; } ?>
更多php中使用Curl、socket、file_get_contents三种方法POST提交数据相关文章请关注PHP中文网!