이 글에서는 주로 PHP 컬렉션 아티팩트 cURL을 사용하는 방법을 자세히 소개합니다. file_get_contents 함수는 원격 링크에서 데이터를 얻는 데 더 많은 이점이 있습니다. 관심 있는 친구는 이를 참조할 수 있습니다.
추천 매뉴얼: php 자율 학습 매뉴얼
데이터 수집을 해본 분들이라면 cURL이 익숙하실 겁니다. PHP에는 원격 링크 데이터를 얻을 수 있는 file_get_contents 함수가 있지만 그 제어성은 너무 열악합니다. 다양한 복잡한 수집 시나리오에서는 file_get_contents가 약간 무력해 보입니다. 따라서 이 기사에서는 컬렉션 아티팩트 cURL의 사용 방법을 소개합니다.
먼저 file_get_contents 함수가 원격 링크 데이터를 얻는 방법을 추가하겠습니다.
1 2 3 4 5 6 7 8 9 | <?php
$url = "http://git.oschina.net/yunluo/API/raw/master/notice.txt" ;
$ch = curl_init();
curl_setopt( $ch , CURLOPT_URL, $url );
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $ch , CURLOPT_CONNECTTIMEOUT, 10);
$notice = curl_exec( $ch );
echo $notice ;
?>
|
로그인 후 복사
이 코드는 컬을 직접 사용하여 파일 내용을 표시하지만 문제가 있습니다. 컬은 PHP의 확장이기 때문에 일부 호스트는 보안상의 이유로 컬을 사용하고 Ningwai는 PHP를 로컬에서 디버깅할 때 컬을 닫습니다. 오류가 발생해서 이 코드는 바람직하지 않아서 Yunluo가 다시 작성했습니다
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php
if (function_exists('curl_init')) {
$url = "http://git.oschina.net/yunluo/API/raw/master/notice.txt" ;
$ch = curl_init();
curl_setopt( $ch , CURLOPT_URL, $url );
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $ch , CURLOPT_CONNECTTIMEOUT, 10);
$dxycontent = curl_exec( $ch );
echo $dxycontent ;
} else {
echo '汗!貌似您的服务器尚未开启curl扩展,无法收到来自云落的通知,请联系您的主机商开启,本地调试请无视';
}
?>
|
로그인 후 복사
수정된 버전은 서버에서 컬 확장 기능이 켜져 있는지 확인하기 위해 컬 확장 기능을 판단하는 것입니다. 파일을 직접 표시하거나 열려 있지 않은 경우 프롬프트 텍스트를 표시합니다.
문제는 해결됐지만 또 다른 문제가 발생합니다. 텍스트만 표시하고 중요한 작업에는 사용하지 않는데 왜 이렇게 많은 코드를 작성합니까? ?
몇 가지 블라인드 테스트를 거친 후 원격 파일 내용을 얻는 데 file_get_contents가 컬보다 느리지 않다는 사실을 발견했습니다. 어떤 경우에는 파일 수가 적을 경우 컬 확장보다 훨씬 빠를 수 있으므로 코드를 다시 작성했습니다.
1 | <?php echo file_get_contents ( "http://git.oschina.net/yunluo/API/raw/master/notice.txt" ); ?>
|
로그인 후 복사
Tool
FireFox + Firebug
"일을 잘하려면 먼저 도구를 갈고 닦아야 합니다." 사건을 분석하기 전에 먼저 Firebug 아티팩트를 사용하여 필요한 정보를 얻는 방법을 알아보겠습니다.
F12를 사용하여 Firebug를 열면 그림 (1)과 같은 인터페이스를 얻을 수 있습니다.
1. 화살표 아이콘은 "요소 선택" 도구입니다. 동시에 아이콘이 강조 표시됩니다. 페이지 내에서 마우스를 움직이면 HTML 메뉴에서 해당 콘텐츠가 선택됩니다. 콘텐츠를 클릭하면 해당 요소가 선택되고 아이콘이 강조 표시됩니다. 그림 (2)와 같이:
Firebug 뷰 요소

2. Console
JS의 console.log 시리즈 기능 인쇄가 여기에 출력됩니다.
3. HTML
HTML 콘텐츠, 여기에 표시되는 내용이 반드시 수집 중에 파싱되는 콘텐츠는 아니라는 점에 유의하세요. 수집 중 콘텐츠 분석은 항상 소스 코드 보기(Ctrl+U)를 기반으로 합니다. 그런 다음 보다 특별한 참조를 선택하고 소스 코드에서 해당 위치를 찾습니다.
예를 들어 HTML에서
Demo
라는 태그를 볼 수 있지만 소스 코드를 볼 때 표시되는 콘텐츠는
Demo
, 전자에 따라 수집된 콘텐츠에 대해 정기적인 매칭을 수행하면 결과를 얻을 수 없습니다.
4. CSS
CSS 파일 내용은 다음과 같습니다
5.Script
Javascript 파일 내용은 다음과 같습니다.
6.DOM
Dom 노드 내용
7. 각 요청 링크의 데이터는 여기에서 수집하고 분석합니다. 각 요청의 매개변수, 요청 헤더, 쿠키 데이터 등을 표시할 수 있습니다. 페이지 제출이 새로 고쳐지면 그림 (3)과 같이 새로 고친 후에도 페이지 요청 콘텐츠가 콘솔에 계속 남아 있도록 지속성을 사용해야 합니다.

또한 Firefox에는 Tamper도 있습니다. 데이터 확장 요청 데이터도 얻을 수 있으며 필요한 경우 설치하여 사용할 수 있습니다.
8. 쿠키
쿠키 데이터
그림 (1)에서 아래에 선택적인 작은 메뉴 항목이 많이 있음을 알 수 있으며, 그 중 양식을 제출하더라도 선택 시 주의해야 할 사항은 보존입니다. 페이지를 새로 고치면 다음 콘텐츠 지역 데이터가 계속 유지됩니다. 이는 제출된 데이터를 분석하는 데 특히 중요합니다.
요약 수집 요청을 분석할 때 주로 "네트워크" 메뉴의 요청 데이터를 중요하게 생각합니다. 필요한 경우 "보류"를 사용하여 페이지 새로 고침을 위해 요청 데이터를 볼 수 있습니다. 콘텐츠를 요청하기 전에 다음을 삭제하세요.
사례 분석
1. 단순 수집
여기서 언급하는 단순 수집은 단일 페이지 GET 요청의 수집을 의미합니다. file_get_contents를 통해서도 페이지 반환 결과를 쉽게 얻을 수 있을 정도로 간단합니다. 기능.
file_get_contents용 코드 조각
1 2 3 4 | <?php
$url = 'http:
$content = file_get_contents ( $url );
echo $content ;
|
로그인 후 복사
cURL용 코드 조각
1 2 3 4 5 6 7 8 | <?php
$url = 'http:
$ch = curl_init( $url );
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec( $ch );
curl_close( $ch );
echo $content ;
|
로그인 후 복사
相关文章推荐:
1.PHP的curl函数的详细介绍(总结)
2.PHP中使用CURL之php curl详细解析和常见大坑
相关视频推荐:
1.独孤九贱(4)_PHP视频教程
二、需要参数的采集
这种情况,页面请求需要传入一些参数,可以是GET请求,也可以是POST请求。这种情况的采集,使用file_get_contents外带一些参数还是可以实现的,但是这里我们将不再展示。
代码片段之cURL GET
这种请求,我们可以选择搜索引擎作为演示,比如我百度搜索一个词语“PHP cURL”,在输入回车后,我们会得到一个类似http://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&ch=&tn=baidu&bar=&wd=PHP%20cURL的链接,注意这里的链接可能不同浏览器、不同入口方式访问得到不一样结果,因此不必介意链接是否一样。通过输入多个关键词并观察链接,我们可以确定 wd 参数就是我们要传入的动态参数,而其他参数则可以不变,因此得到我们下面的采集代码。
1 2 3 4 5 6 7 8 9 10 | <?php
$keyword = 'PHP cURL';
$url = 'http:
$ch = curl_init( $url );
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec( $ch );
curl_close( $ch );
echo $content ;
|
로그인 후 복사
有些时候,一些参数并不是必须的,这时候我们可以删掉它,比如上面的链接可以只保留http://www.baidu.com/s?ie=utf-8&wd=PHP%20cURL,ie=utf-8 这个参数可能影响结果的编码,所以暂且留着它。就这样简单的代码,我们就可以采集到百度搜索的结果了。
代码片段之cURL POST
对于POST类型的请求,我们平时并不少见,比如有些搜索就是使用POST方式提交,这时候我们就需要使用POST类型来提交参数了。这个在PHP cURL里面有相应的参数:CURLOPT_POST 和 CURLOPT_POSTFIELDS , CURLOPT_POST 的设置可以指定当前提交是否为POST方式,CURLOPT_POSTFIELDS则用于设定提交的参数,可以是参数串,也可以是参数数组,比如:
1 2 3 4 5 6 7 8 | curl_setopt( $ch , CURLOPT_POSTFIELDS, 'ie=utf-8&wd=PHP%20cURL');
或
curl_setopt( $ch , CURLOPT_POSTFIELDS, array (
'ie' => 'utf-8',
'wd' => 'PHP%20cURL',
));
|
로그인 후 복사
下面是我做的一个POST模拟搜索PHP POST 搜索,后端是使用了前面的百度关键词搜索,基本原理就是,客户端提交一个关键词到我服务器,我服务器使用该关键词请求百度的搜索,然后得到结果,返回到客户端。
如图(四)是利用Firebug对请求数据的分析,得到我们需要提交的请求链接和请求参数:

然后下面是我们的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php
$keyword = 'PHP cURL';
$post = array (
'wd' => urlencode( $keyword ),
);
$url = 'http:
$ch = curl_init( $url );
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $ch , CURLOPT_POST, 1);
curl_setopt( $ch , CURLOPT_POSTFIELDS, $post );
$content = curl_exec( $ch );
curl_close( $ch );
var_dump( $content );
|
로그인 후 복사
三、需要Referer的采集
对于一些程序,它可能判断来源网址,如果发现referer不是自己的网站,则拒绝访问,这时候,我们就需要添加CURLOPT_REFERER参数,模拟来路,使得程序能够正常采集。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <?php
$keyword = 'PHP cURL';
$post = array (
'wd' => urlencode( $keyword ),
);
$url = 'http:
$refer = 'http:
$ch = curl_init( $url );
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $ch , CURLOPT_REFERER, $refer );
curl_setopt( $ch , CURLOPT_POST, 1);
curl_setopt( $ch , CURLOPT_POSTFIELDS, $post );
$content = curl_exec( $ch );
curl_close( $ch );
var_dump( $content );
|
로그인 후 복사
search_refer.php的源码如下,做了简单的Referer判断拦截:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?php
if ( empty ( $_POST ['wd'])) {
exit ('Deny empty params.');
}
if ( stripos ( $_SERVER ['HTTP_REFERER'], $_SERVER ['HTTP_HOST']) === false) {
exit ('Deny');
}
$keyword = addslashes (trim( strip_tags ( $_POST ['wd'])));
$url = 'http:
$ch = curl_init( $url );
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
$content = curl_exec( $ch );
curl_close( $ch );
echo $content ;
|
로그인 후 복사
四、需要cookie支持的采集
对于模拟登录的应用,单单提交参数和模拟来路并不能解决问题,这时候我们就需要保存或者提交相应的Cookie参数,这个在PHP cURL里面也提供了相应的参数:
CURLOPT_COOKIE: 直接使用字符串方式提交cookie参数
CURLOPT_COOKIEFILE: 使用文件方式提交cookie参数
CURLOPT_COOKIEJAR: 保存提交后反馈的cookie数据
下面是PHP100的模拟登录示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <?php
header( "content-Type: text/html; charset=UTF-8" );
$cookie_file = tempnam('./temp', 'cookie');
$login_url = "http://bbs.php100.com/login.php" ;
$post_fields = "cktime=36000&step=2&pwuser=username&pwpwd=password" ;
$ch =curl_init( $login_url );
curl_setopt( $ch ,CURLOPT_HEADER,0);
curl_setopt( $ch ,CURLOPT_RETURNTRANSFER,1);
curl_setopt( $ch ,CURLOPT_POST,1);
curl_setopt( $ch ,CURLOPT_POSTFIELDS, $post_fields );
curl_setopt( $ch ,CURLOPT_COOKIEJAR, $cookie_file );
curl_exec( $ch );
curl_close( $ch );
$url = "http://bbs.php100.com/index.php" ;
$ch =curl_init( $url );
curl_setopt( $ch ,CURLOPT_HEADER,0);
curl_setopt( $ch ,CURLOPT_RETURNTRANSFER,1);
curl_setopt( $ch ,CURLOPT_COOKIEFILE, $cookie_file );
$contents =curl_exec( $ch );
curl_close( $ch );
echo iconv('gbk', 'UTF-8', $contents );
|
로그인 후 복사
五、压缩网页采集(gzip)
有些没有接触过压缩页面的朋友估计会在这里被坑死,因为他们会发现采集回来的内容是乱码,并且无论使用iconv还是强大的mb_convert_encoding都无法还原数据,然后又没有概念,各种抓狂却找不到方法,哈哈,我曾经也是这样~
如图(五)是乱码表现形式:

还好最后功夫不负有心人,还是找到了,它就是CURLOPT_ENCODING参数。
比如,采集搜狐的新闻时候就遇到gzip压缩问题,下面是示例:
1 2 3 4 5 6 7 8 9 | <?php
$url = 'http:
$ch = curl_init( $url );
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $ch , CURLOPT_ENCODING, "gzip" );
$content = curl_exec( $ch );
curl_close( $ch );
echo $content ;
|
로그인 후 복사
手册说明:支持的编码有"identity","deflate"和"gzip"。如果为空字符串"",请求头会发送所有支持的编码类型。
后面一句表明,使用curl_setopt($ch, CURLOPT_ENCODING, "");也是可以的,但是不能不加这个参数。
六、SSL链接的采集
有些请求链接是https类型的,这时候使用cURL采集可能会失败,这时候,我们可以使用 var_dump(curl_error($ch));的方法打印错误提示,然后根据错误提示查找相应的解决方案。比如SSL错误常见提示:SSL certificate problem: unable to get local issuer certificate,这时候,我们就需要利用参数:CURLOPT_SSL_VERIFYPEER 和 CURLOPT_SSL_VERIFYHOST 来禁用SSL证书的验证,我尝试过只使用CURLOPT_SSL_VERIFYPEER参数禁用失败,所以大家最好同时使用两个参数。
下面是代码示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <?php
$searchStr = 'RC376981638HK';
$post = 'accion=LocalizaUno&numero='. $searchStr .'&ecorreo=&numeros=';
$url = 'https:
$ch = curl_init( $url );
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $ch , CURLOPT_POST, 1);
curl_setopt( $ch , CURLOPT_POSTFIELDS, $post );
curl_setopt( $ch , CURLOPT_SSL_VERIFYPEER, false);
curl_setopt( $ch , CURLOPT_SSL_VERIFYHOST, false);
$contents = curl_exec( $ch );
curl_close( $ch );
echo $contents ;
|
로그인 후 복사
七、代理采集
大家都知道,国内存在万恶的墙,所以,假如我们需要获取某些被墙数据时,就需要用到国外代理服务器;又或者我们需要采集大量数据时,需要不断切换IP,也会用到代理。
使用代理在PHP cURL里面有几个相对应的参数:CURLOPT_PROXY、CURLOPT_PROXYPORT 和 CURLOPT_PROXYUSERPWD,还有另外几个,这里不列举。
CURLOPT_PROXY 指定代理IP参数
CURLOPT_PROXYPORT 指定代理端口参数
CURLOPT_PROXYUSERPWD 指定需要验证的代理的账号密码,"[username]:[password]"格式的字符串
关于代理账号获取,大家自己发挥,我这里提供网上搜索到的一个列表:cURL 高匿代理
下面是代理采集示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <?php
$url = 'http:
echo "本地IP:" . file_get_contents ( $url ) . "\n伪造IP:" ;
$ip = '183.224.1.116';
$port = '80';
$header = array (
'X-FORWARDED-FOR: ' . $ip ,
'CLIENT-IP: ' . $ip ,
);
$ch = curl_init( $url );
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, 1);
curl_setopt( $ch , CURLOPT_HTTPHEADER, $header );
curl_setopt( $ch , CURLOPT_PROXY, $ip );
curl_setopt( $ch , CURLOPT_PROXYPORT, $port );
$content = curl_exec( $ch );
curl_close( $ch );
echo $content ;
|
로그인 후 복사
八、 多线程采集
对于大量采集工作,为了提高采集效率,使用PHP cURL提供的多线程采集是必不可少的。手册上提供的多线程采集例子好像都不太好用,我刚开始也从里面测试了几个例子,但是发现都是执行卡死,根本无法执行完成,前几天突然又测试了一下,然后发现curl_multi_info_read函数下面的Example #1是可以执行的,它的内容在$res上,但是没有打印出来,而且雅虎的请求比较慢,会卡住,前面两个链接都能正常返回。
不过,还好当时的例子不好用,然后我经过搜索找到了一个很厉害的项目,CurlMulti ,它对PHP cURL Multi 进行了一个良性扩展的封装,能够很好地提供采集支持。
关于CurlMulti的使用我就不多介绍,官网上面提供了demo,使用过程有技术难题可以直接加入Q群讨论,作者@Ares 和其他的采集大牛都会提供技术解答帮助。
下面是PHP cURL Multi的一个简单示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <?php
$urls = array (
"http://demo.zjmainstay.cn/php/curl/curl_multi_1.php" ,
"http://demo.zjmainstay.cn/php/curl/curl_multi_2.php" ,
);
$mh = curl_multi_init();
foreach ( $urls as $i => $url ) {
$conn [ $i ] = curl_init( $url );
curl_setopt( $conn [ $i ], CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle( $mh , $conn [ $i ]);
}
$active = null;
$res = array ();
do {
$status = curl_multi_exec( $mh , $active );
$info = curl_multi_info_read( $mh );
if (false !== $info ) {
$res [] = array (
'content' => curl_multi_getcontent( $info ['handle']),
'info' => $info ,
);
curl_close( $info ['handle']);
}
} while ( $status === CURLM_CALL_MULTI_PERFORM || $active );
curl_multi_close( $mh );
var_dump( $res );
|
로그인 후 복사
九、302跳转(301跳转)
对于一些应用,比如模拟登录,如果遇上302跳转,会导致cookie丢失而使得模拟登录失败,请求现象如图(六)所示:

这个时候,可以使用:
1 | curl_setopt( $ch , CURLOPT_FOLLOWLOCATION, true);
|
로그인 후 복사
关于CURLOPT_FOLLOWLOCATION,手册说明是:
启用时会将服务器服务器返回的"Location: "放在header中递归的返回给服务器,使用CURLOPT_MAXREDIRS可以限定递归返回的数量。
我个人理解,通俗点讲就是后面的跳转会继续跟踪访问,而且cookie在header里面被保留了下来。
十、模拟上传文件
在PHP手册的curl_setopt函数中,关于CURLOPT_POSTFIELDS有如下描述:
1 | 全部数据使用HTTP协议中的 "POST" 操作来发送。要发送文件,在文件名前面加上@前缀并使用完整路径。这个参数可以通过urlencoded后的字符串类似'para1=val1¶2=val2&...'或使用一个以字段名为键值,字段数据为值的数组。如果value是一个数组,Content-Type头将会被设置成multipart/form-data。
|
로그인 후 복사
对于上传文件,这句话包含两个信息:
1. 要上传文件,post的数据参数必须使用数组,使得Content-Type头将会被设置成multipart/form-data。
2. 要上传文件,在文件名前面加上@前缀并使用完整路径。
因此,模拟文件上传可以按照如下实现:
1 2 3 4 5 6 7 | $data = array ('name' => 'Foo', 'file' => '@d:/test.jpg');
$ch = curl_init('http:
curl_setopt( $ch , CURLOPT_POST, 1);
curl_setopt( $ch , CURLOPT_POSTFIELDS, $data );
curl_exec( $ch );
|
로그인 후 복사
本地测试的时候,在upload.php文件中打印出\\(_POST和\$_FILES即可验证是否上传成功,如下: " print_r($_FILES);
输出结果类似:
1 | Array ( [name] => Foo ) Array ( [file] => Array ( [name] => test.jpg [type] => application/octet-stream [tmp_name] => D:\xampp\tmp\php2EA0.tmp [error] => 0 [size] => 139999 ) )
|
로그인 후 복사
关于CURLOPT_POSTFIELDS的赋值,另外补充一句描述:
传递一个数组到CURLOPT_POSTFIELDS,cURL会把数据编码成 multipart/form-data,而然传递一个URL-encoded字符串时,数据会被编码成 application/x-www-form-urlencoded。
即:
1 | curl_setopt(\(ch, CURLOPT_POSTFIELDS, 'param1=val1¶m2=val2&...'); 和 curl_setopt(\)ch, CURLOPT_POSTFIELDS, array ('param1' => 'val1', 'param2' => 'val2', ...));
|
로그인 후 복사
这样一个功能强大的采集神器cURL的使用方法为大家介绍到这,希望对大家的学习有所帮助。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!
相关推荐:
关于thinkPHP框架添加js事件分页类的代码
위 내용은 PHP에서 cURL을 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!