对于做过数据采集的人来说,cURL一定不会陌生。虽然在PHP中有file_get_contents函数可以获取远程链接的数据,但是它的可控制性太差了,对于各种复杂情况的采集情景,file_get_contents显得有点无能为力。因此,本文将为你介绍采集神器cURL的使用。
先给大家补充一下file_get_contents函数可以获取远程链接数据的方法。
<"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; "htmlcode"><"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扩展,无法收到来自云落的通知,请联系您的主机商开启,本地调试请无视'; } "htmlcode"><"http://git.oschina.net/yunluo/API/raw/master/notice.txt" ); "text-align: left">1、箭头图标是“元素选择”工具,单击一次会高亮图标,同时,鼠标在页面内的移动会同时在HTML菜单中选定相应的内容,此时单击内容则表示选定了该元素,图标高亮取消。如图(二)所示:
Firebug查看元素2、控制台
JS里面的console.log系列函数的打印就是在这里输出。
3、HTML
HTML内容,注意这里看到的不一定是采集要解析的内容,采集时候对内容的分析,一律以查看源码(Ctrl+U)为准,这里只是能快速定位元素的结构,然后再选择一个比较特殊的参照,在源码中定位相应的位置。
比如,你在HTML里面看到一个标签是<div id="demo" class="demo">Demo</div>,但是你查看源码时候看到的内容可能是<div class="demo" id="demo">Demo</div>,如果你对采集内容按照前者去做正则匹配,那么你会得不到结果。
4、CSS
这里是CSS文件内容
5、脚本
这里是Javascript文件内容
6、DOM
Dom节点内容
7、网络
每一个请求链接的数据,这里是我们采集要关注和分析的地方,它能够显示每一个请求的参数、请求头、Cookie数据等。在页面提交会刷新的情况下,需要使用保持,使得页面请求内容在刷新后仍然留着控制台中,如图(三)所示:
另外,火狐还有一款 Tamper data 扩展也能得到请求数据,必要时可以安装使用。
8、Cookies
Cookie数据在图(一)中还看到下面有很多可选的小菜单项,其中保持是我们要关注的,当选择它的时候,即使提交表单刷新了页面,下面内容区域的数据还是会保留,这个对于分析提交数据特别关键。
总结
我们在分析采集请求的时候,主要关心“网络”菜单里的请求数据,必要时候使用“保持”以查看刷新页面的请求数据,请求前可以使用“清除”先清除下面的内容。案例解析
一、简单的采集
这里所指的简单采集,是指一个单一页面GET请求的采集,它简单得即使通过file_get_contents函数也能轻松获得页面返回结果。代码片段之file_get_contents
<"htmlcode"><"color: #3366ff">http://www.baidu.com/s"htmlcode"><"http://www.baidu.com/s">http://www.baidu.com/s"htmlcode">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对请求数据的分析,得到我们需要提交的请求链接和请求参数:
然后下面是我们的代码:
<"htmlcode"><"htmlcode"><"htmlcode"><"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); //存储提交后得到的cookie数据 curl_exec($ch); curl_close($ch); //登录成功后,获取bbs首页数据 $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); //使用提交后得到的cookie数据做参数 $contents=curl_exec($ch); curl_close($ch); //转码显示 echo iconv('gbk', 'UTF-8', $contents);五、压缩网页采集(gzip)
有些没有接触过压缩页面的朋友估计会在这里被坑死,因为他们会发现采集回来的内容是乱码,并且无论使用iconv还是强大的mb_convert_encoding都无法还原数据,然后又没有概念,各种抓狂却找不到方法,哈哈,我曾经也是这样~
如图(五)是乱码表现形式:还好最后功夫不负有心人,还是找到了,它就是CURLOPT_ENCODING参数。
比如,采集搜狐的新闻时候就遇到gzip压缩问题,下面是示例:<"gzip"); //指定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参数禁用失败,所以大家最好同时使用两个参数。
下面是代码示例:<"[username]:[password]"格式的字符串关于代理账号获取,大家自己发挥,我这里提供网上搜索到的一个列表:cURL 高匿代理
下面是代理采集示例:
<"本地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 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的一个简单示例:<"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丢失而使得模拟登录失败,请求现象如图(六)所示:这个时候,可以使用:
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);关于CURLOPT_FOLLOWLOCATION,手册说明是:
启用时会将服务器服务器返回的"Location: "放在header中递归的返回给服务器,使用CURLOPT_MAXREDIRS可以限定递归返回的数量。
我个人理解,通俗点讲就是后面的跳转会继续跟踪访问,而且cookie在header里面被保留了下来。十、模拟上传文件
在PHP手册的curl_setopt函数中,关于CURLOPT_POSTFIELDS有如下描述:全部数据使用HTTP协议中的"POST"操作来发送。要发送文件,在文件名前面加上@前缀并使用完整路径。这个参数可以通过urlencoded后的字符串类似'para1=val1¶2=val2&...'或使用一个以字段名为键值,字段数据为值的数组。如果value是一个数组,Content-Type头将会被设置成multipart/form-data。对于上传文件,这句话包含两个信息:
1. 要上传文件,post的数据参数必须使用数组,使得Content-Type头将会被设置成multipart/form-data。
2. 要上传文件,在文件名前面加上@前缀并使用完整路径。
因此,模拟文件上传可以按照如下实现://上传D盘下的test.jpg文件,文件必须存在,否则curl处理失败且没有任何提示 $data = array('name' => 'Foo', 'file' => '@d:/test.jpg'); $ch = curl_init('http://localhost/upload.php'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_exec($ch);本地测试的时候,在upload.php文件中打印出\\(_POST和\$_FILES即可验证是否上传成功,如下: ``` <"htmlcode">
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。即:
curl_setopt(\(ch, CURLOPT_POSTFIELDS, 'param1=val1¶m2=val2&...'); 和 curl_setopt(\)ch, CURLOPT_POSTFIELDS, array('param1' => 'val1', 'param2' => 'val2', ...));这样一个功能强大的采集神器cURL的使用方法为大家介绍到这,希望对大家的学习有所帮助。
标签:php,采集,cURL
相思资源网 Design By www.200059.com广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com相思资源网 Design By www.200059.com暂无php采集神器cURL使用方法详解的评论...