PHP cURL 应用文档格式.docx
《PHP cURL 应用文档格式.docx》由会员分享,可在线阅读,更多相关《PHP cURL 应用文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
这里是Javascript文件内容
6.DOM
Dom节点内容
7.网络
每一个请求链接的数据,这里是我们采集要关注和分析的地方,它能够显示每一个请求的参数、请求头、Cookie数据等。
在页面提交会刷新的情况下,需要使用保持,使得页面请求内容在刷新后仍然留着控制台中,如图(三)所示:
另外,火狐还有一款Tamperdata扩展也能得到请求数据,必要时可以安装使用。
8.Cookies
Cookie数据
在图
(一)中还看到下面有很多可选的小菜单项,其中保持是我们要关注的,当选择它的时候,即使提交表单刷新了页面,下面内容区域的数据还是会保留,这个对于分析提交数据特别关键。
总结
我们在分析采集请求的时候,主要关心“网络”菜单里的请求数据,必要时候使用“保持”以查看刷新页面的请求数据,请求前可以使用“清除”先清除下面的内容。
案例解析
一、简单的采集
这里所指的简单采集,是指一个单一页面GET请求的采集,它简单得即使通过file_get_contents函数也能轻松获得页面返回结果。
∙代码片段之file_get_contents
<
?
php
$url='
$content=file_get_contents($url);
echo$content;
∙代码片段之cURL
$ch=curl_init($url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
//返回数据不直接输出
$content=curl_exec($ch);
//执行并存储结果
curl_close($ch);
二、需要参数的采集
这种情况,页面请求需要传入一些参数,可以是GET请求,也可以是POST请求。
这种情况的采集,使用file_get_contents外带一些参数还是可以实现的,但是这里我们将不再展示。
∙代码片段之cURLGET
这种请求,我们可以选择搜索引擎作为演示,比如我XX搜索一个词语“PHPcURL”,在输入回车后,我们会得到一个类似wd参数就是我们要传入的动态参数,而其他参数则可以不变,因此得到我们下面的采集代码。
$keyword='
PHPcURL'
;
.urlencode($keyword);
有些时候,一些参数并不是必须的,这时候我们可以删掉它,比如上面的链接可以只保留这个参数可能影响结果的编码,所以暂且留着它。
就这样简单的代码,我们就可以采集到XX搜索的结果了。
∙代码片段之cURLPOST
对于POST类型的请求,我们平时并不少见,比如有些搜索就是使用POST方式提交,这时候我们就需要使用POST类型来提交参数了。
这个在PHPcURL里面有相应的参数:
CURLOPT_POST和CURLOPT_POSTFIELDS,CURLOPT_POST的设置可以指定当前提交是否为POST方式,CURLOPT_POSTFIELDS则用于设定提交的参数,可以是参数串,也可以是参数数组,比如:
curl_setopt($ch,CURLOPT_POSTFIELDS,'
ie=utf-8&
wd=PHP%20cURL'
);
或
curl_setopt($ch,CURLOPT_POSTFIELDS,array(
'
ie'
=>
utf-8'
wd'
PHP%20cURL'
));
下面是我做的一个POST模拟搜索PHPPOST搜索,后端是使用了前面的XX关键词搜索,基本原理就是,客户端提交一个关键词到我服务器,我服务器使用该关键词请求XX的搜索,然后得到结果,返回到客户端。
如图(四)是利用Firebug对请求数据的分析,得到我们需要提交的请求链接和请求参数:
然后下面是我们的代码:
//参数方法一
//$post='
wd='
//参数方法二
$post=array(
urlencode($keyword),
);
curl_setopt($ch,CURLOPT_POST,1);
//发送POST类型数据
curl_setopt($ch,CURLOPT_POSTFIELDS,$post);
//POST数据,$post可以是数组,也可以是拼接
var_dump($content);
三、需要Referer的采集
对于一些程序,它可能判断来源网址,如果发现referer不是自己的网站,则拒绝访问,这时候,我们就需要添加CURLOPT_REFERER参数,模拟来路,使得程序能够正常采集。
$refer='
//来路地址
curl_setopt($ch,CURLOPT_REFERER,$refer);
//来路模拟
search_refer.php的源码如下,做了简单的Referer判断拦截:
if(empty($_POST['
])){
exit('
Denyemptyparams.'
}
//Referer判断
if(stripos($_SERVER['
HTTP_REFERER'
],$_SERVER['
HTTP_HOST'
])===false){
Deny'
$keyword=addslashes(trim(strip_tags($_POST['
])));
四、需要cookie支持的采集
对于模拟登录的应用,单单提交参数和模拟来路并不能解决问题,这时候我们就需要保存或者提交相应的Cookie参数,这个在PHPcURL里面也提供了相应的参数:
CURLOPT_COOKIE:
直接使用字符串方式提交cookie参数
CURLOPT_COOKIEFILE:
使用文件方式提交cookie参数
CURLOPT_COOKIEJAR:
保存提交后反馈的cookie数据
下面是PHP100的模拟登录示例:
php
header("
content-Type:
text/html;
charset=UTF-8"
$cookie_file=tempnam('
./temp'
'
cookie'
$login_url="
$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);
//存储提交后得到的cookie数据
curl_exec($ch);
curl_close($ch);
//登录成功后,获取bbs首页数据
$url="
$ch=curl_init($url);
curl_setopt($ch,CURLOPT_COOKIEFILE,$cookie_file);
//使用提交后得到的cookie数据做参数
$contents=curl_exec($ch);
//转码显示
echoiconv('
gbk'
UTF-8'
$contents);
五、压缩网页采集(gzip)
有些没有接触过压缩页面的朋友估计会在这里被坑死,因为他们会发现采集回来的内容是乱码,并且无论使用iconv还是强大的mb_convert_encoding都无法还原数据,然后又没有概念,各种抓狂却找不到方法,哈哈,我曾经也是这样~
如图(五)是乱码表现形式:
还好最后功夫不负有心人,还是找到了,它就是CURLOPT_ENCODING参数。
比如,采集搜狐的新闻时候就遇到gzip压缩问题,下面是示例:
curl_setopt($ch,CURLOPT_ENCODING,"
gzip"
//指定gzip压缩
手册说明:
支持的编码有"
identity"
,"
deflate"
和"
。
如果为空字符串"
"
,请求头会发送所有支持的编码类型。
后面一句表明,使用curl_setopt($ch,CURLOPT_ENCODING,"
也是可以的,但是不能不加这个参数。
六、SSL链接的采集
有些请求链接是https类型的,这时候使用cURL采集可能会失败,这时候,我们可以使用var_dump(curl_error($ch));
的方法打印错误提示,然后根据错误提示查找相应的解决方案。
比如SSL错误常见提示:
SSLcertificateproblem:
unabletogetlocalissuercertificate,这时候,我们就需要利用参数:
CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST来禁用SSL证书的验证,我尝试过只使用CURLOPT_SSL_VERIFYPEER参数禁用失败,所以大家最好同时使用两个参数。
下面是代码示例:
$searchStr='
RC376981638HK'
$post='
accion=LocalizaUno&
numero='
.$searchStr.'
&
ecorreo=&
numeros='
https:
//aplicacionesweb.correos.es/localizadorenvios/track.asp'
//初始化curl
//POST数据,$post可以是数组,也可以是拼接参数串
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
//SSL报错时使用
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
$contents=curl_exec($ch);
//var_dump(curl_error($ch));
//获取失败是使用(采集错误提示)
echo$contents;
七、代理采集
大家都知道,国内存在万恶的墙,所以,假如我们需要获取某些被墙数据时,就需要用到国外代理服务器;
又或者我们需要采集大量数据时,需要不断切换IP,也会用到代理。
使用代理在PHPcURL里面有几个相对应的参数:
CURLOPT_PROXY、CURLOPT_PROXYPORT和CURLOPT_PROXYUSERPWD,还有另外几个,这里不列举。
CURLOPT_PROXY指定代理IP参数
CURLOPT_PROXYPORT指定代理端口参数
CURLOPT_PROXYUSERPWD指定需要验证的代理的账号密码,"
[username]:
[password]"
格式的字符串
关于代理账号获取,大家自己发挥,我这里提供网上搜索到的一个列表:
cURL高匿代理
下面是代理采集示例:
.time();
echo"
本地IP:
.file_get_contents($url)."
\n伪造IP:
$ip='
183.224.1.116'
$port='
80'
//伪造请求头参数,如果是高匿代理这里不需要提供
$header=array(
X-FORWARDED-FOR:
.$ip,
CLIENT-IP:
curl_setopt($ch,CURLOPT_HTTPHEADER,$header);
curl_setopt($ch,CURLOPT_PROXY,$ip);
curl_setopt($ch,CURLOPT_PROXYPORT,$port);
八、多线程采集
对于大量采集工作,为了提高采集效率,使用PHPcURL提供的多线程采集是必不可少的。
手册上提供的多线程采集例子好像都不太好用,我刚开始也从里面测试了几个例子,但是发现都是执行卡死,根本无法执行完成,前几天突然又测试了一下,然后发现curl_multi_info_read函数下面的Example#1是可以执行的,它的内容在$res上,但是没有打印出来,而且雅虎的请求比较慢,会卡住,前面两个链接都能正常返回。
不过,还好当时的例子不好用,然后我经过搜索找到了一个很厉害的项目,CurlMulti,它对PHPcURLMulti进行了一个良性扩展的封装,能够很好地提供采集支持。
关于CurlMulti的使用我就不多介绍,官网上面提供了demo,使用过程有技术难题可以直接加入Q群讨论,作者@Ares和其他的采集大牛都会提供技术解答帮助。
下面是PHPcURLMulti的一个简单示例:
$urls=array(
"
$mh=curl_multi_init();
foreach($urlsas$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['
]);
}while($status===CURLM_CALL_MULTI_PERFORM||$active);
curl_multi_close($mh);
var_dump($res);
九、302跳转(301跳转)
对于一些应用,比如模拟登录,如果遇上302跳转,会导致cookie丢失而使得模拟登录失败,请求现象如图(六)所示:
这个时候,可以使用:
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);
关于CURLOPT_FOLLOWLOCATION,手册说明是:
启用时会将服务器服务器返回的"
Location:
放在header中递归的返回给服务器,使用CURLOPT_MAXREDIRS可以限定递归返回的数量。
我个人理解,通俗点讲就是后面的跳转会继续跟踪访问,而且cookie在header里面被保留了下来。
十、模拟上传文件
在PHP手册的curl_setopt函数中,关于CURLOPT_POSTFIELDS有如下描述:
全部数据使用HTTP协议中的"
POST"
操作来发送。
要发送文件,在文件名前面加上@前缀并使用完整路径。
这个参数可以通过urlencoded后的字符串类似'
para1=val1&
para2=val2&
...'
或使用一个以字段名为键值,字段数据为值的数组。
如果value是一个数组,Content-Type头将会被设置成multipart/form-data。
对于上传文件,这句话包含两个信息:
1.要上传文件,post的数据参数必须使用