• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

php采集神器cURL使用方法详解_php实例

php 搞代码 3年前 (2022-01-26) 41次浏览 已收录 0个评论

对于做过数据采集的人来说,cURL一定不会陌生。虽然在PHP中有file_get_contents函数可以获取远程链接的数据,但是它的可控制性太差了,对于各种复杂情况的采集情景,file_get_contents显得有点无能为力。因此,本文将为你介绍采集神器cURL的使用。

先给大家补充一下file_get_contents函数可以获取远程链接数据的方法。


这段代码会直接使用curl显示文件内容,但是问题来了,因为curl是php的扩展,有的主机为了安全会金庸curl的,宁外php本地调试的时候也是关闭curl的,所以会发生报错,所以这段代码是不可取的,所以云落对他重新改写了


修改后的版本是对curl扩展做一个判断,看看服务器到底有木有打开本#文来源gaodai$ma#com搞$$代**码网$curl扩展,如果打开了,就直接显示文件,如果没打开就显示一段提示文字。
虽然修复了问题,但是又有一个问题来了,我只是显示一段文字而已,我也不是是用什么做什么大事的,所以我为什么要写那么多的代码呢??
经过一些瞎掰的检测,发现file_get_contents获取远程文件内容的速度不比curl慢,在一些文件较少的情况下可能还比curl扩展要快得多,所以我又重写了代码


工具
火狐浏览器(FireFox) + Firebug
“工欲善其事,必先利其器。” 在分析案例之前,先让我们学习一下如何利用神器Firebug获取我们必要的信息。
使用F12打开Firebug,我们可以得到如图(一)界面:

2、控制台
JS里面的console.log系列函数的打印就是在这里输出。
3、HTML
HTML内容,注意这里看到的不一定是采集要解析的内容,采集时候对内容的分析,一律以查看源码(Ctrl+U)为准,这里只是能快速定位元素的结构,然后再选择一个比较特殊的参照,在源码中定位相应的位置。
比如,你在HTML里面看到一个标签是

Demo

,但是你查看源码时候看到的内容可能是

Demo

,如果你对采集内容按照前者去做正则匹配,那么你会得不到结果。
4、CSS
这里是CSS文件内容
5、脚本
这里是Javascript文件内容
6、DOM
Dom节点内容
7、网络
每一个请求链接的数据,这里是我们采集要关注和分析的地方,它能够显示每一个请求的参数、请求头、Cookie数据等。在页面提交会刷新的情况下,需要使用保持,使得页面请求内容在刷新后仍然留着控制台中,如图(三)所示:

然后下面是我们的代码:

 urlencode($keyword),  );  $url    = 'http://demo.zjmainstay.cn/php/curl/search.php';    $ch = curl_init($url);  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据不直接输出  curl_setopt($ch, CURLOPT_POST, 1);      //发送POST类型数据  curl_setopt($ch, CURLOPT_POSTFIELDS, $post); //POST数据,$post可以是数组,也可以是拼接  $content = curl_exec($ch);          //执行并存储结果  curl_close($ch);    var_dump($content);

三、需要Referer的采集
对于一些程序,它可能判断来源网址,如果发现referer不是自己的网站,则拒绝访问,这时候,我们就需要添加CURLOPT_REFERER参数,模拟来路,使得程序能够正常采集。

 urlencode($keyword),  );  $url    = 'http://demo.zjmainstay.cn/php/curl/search_refer.php';  $refer   = 'http://demo.zjmainstay.cn/';  //来路地址    $ch = curl_init($url);  curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //返回数据不直接输出  curl_setopt($ch, CURLOPT_REFERER, $refer);  //来路模拟  curl_setopt($ch, CURLOPT_POST, 1);      //发送POST类型数据  curl_setopt($ch, CURLOPT_POSTFIELDS, $post); //POST数据,$post可以是数组,也可以是拼接  $content = curl_exec($ch);          //执行并存储结果  curl_close($ch);    var_dump($content);

search_refer.php的源码如下,做了简单的Referer判断拦截:

<?php  if(empty($_POST['wd'])) {    exit('Deny empty params.');  }    //Referer判断  if(stripos($_SERVER['HTTP_REFERER'], $_SERVER['HTTP_HOST']) === false) {    exit('Deny');  }    $keyword  = addslashes(trim(strip_tags($_POST['wd'])));  $url    = 'http://www.baidu.com/s?ie=utf-8&wd=' . urlencode($keyword);    $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的模拟登录示例:

<?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); //存储提交后得到的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都无法还原数据,然后又没有概念,各种抓狂却找不到方法,哈哈,我曾经也是这样~
如图(五)是乱码表现形式:

这个时候,可以使用:

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的数据参数必须使用数组,使得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即可验证是否上传成功,如下: “` <?php print_r(\)_POST);
print_r($_FILES);

输出结果类似:

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&param2=val2&...'); 和 curl_setopt(\)ch, CURLOPT_POSTFIELDS, array('param1' => 'val1', 'param2' => 'val2', ...));

这样一个功能强大的采集神器cURL的使用方法为大家介绍到这,希望对大家的学习有所帮助。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:php采集神器cURL使用方法详解_php实例

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址