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

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

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

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

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

工具

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

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

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

另外,火狐还有一款 Tamper data 扩展也能得到请求数据,必要时可以安装使用。 8、Cookies Cookie数据

在图(一)中还看到下面有很多可选的小菜单项,其中保持是我们要关注的,当选择它的时候,即使提交表单刷新了页面,下面内容区域的数据还是会保留,这个对于分析提交数据特别关键。

总结

我们在分析采集请求的时候,主要关心“网络”菜单里的请求数据,必要时候使用“保持”以查看刷新页面的请求数据,请求前可以使用“清除”先清除下面的内容。

案例解析

一、简单的采集

这里所指的简单采集,是指一个单一页面GET请求的采集,它简单得即使通过file_get_contents函数也能轻松获得页面返回结果。

代码片段之file_get_contents

代码片段之cURL

echo $content;

二、需要参数的采集

这种情况,页面请求需要传入一些参数,可以是GET请求,也可以是POST请求。这种情况的采集,使用file_get_contents外带一些参数还是可以实现的,但是这里我们将不再展示。

代码片段之cURL GET 这种请求,我们可以选择搜索引擎作为演示,比如我百度搜索一个词语“PHP cURL”,在输入回车后,我们会得到一个类似

$ch = curl_init($url);
curl_setopt($ch,1); //返回数据不直接输出
$content = curl_exec($ch); //执行并存储结果
curl_close($ch);

echo $content;

有些时候,一些参数并不是必须的,这时候我们可以删掉它,比如上面的链接可以只保留,ie=utf-8 这个参数可能影响结果的编码,所以暂且留着它。就这样简单的代码,我们就可以采集到百度搜索的结果了。

代码片段之cURL POST 对于POST类型的请求,我们平时并不少见,比如有些搜索就是使用POST方式提交,这时候我们就需要使用POST类型来提交参数了。这个在PHP cURL里面有相应的参数:CURLOPT_POST 和 CURLOPT_POSTFIELDS , CURLOPT_POST 的设置可以指定当前提交是否为POST方式,CURLOPT_POSTFIELDS则用于设定提交的参数,可以是参数串,也可以是参数数组,比如:

curl_setopt($ch,array(
'ie' => 'utf-8','wd' => 'PHP%20cURL',));

下面是我做的一个POST模拟搜索PHP POST 搜索,后端是使用了前面的百度关键词搜索,基本原理就是,客户端提交一个关键词到我服务器,我服务器使用该关键词请求百度的搜索,然后得到结果,返回到客户端。 如图(四)是利用Firebug对请求数据的分析,得到我们需要提交的请求链接和请求参数:

然后下面是我们的代码:

//参数方法二
$post = array(
'wd' => urlencode($keyword),);
$url = '
http://demo.zjmainstay.cn/php/curl/search.php';

$ch = curl_init($url);
curl_setopt($ch,1); //返回数据不直接输出
curl_setopt($ch,CURLOPT_POST,1); //发送POST类型数据
curl_setopt($ch,$post); //POST数据,$post可以是数组,也可以是拼接
$content = curl_exec($ch); //执行并存储结果
curl_close($ch);

var_dump($content);

三、需要Referer的采集

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

<div class="jb51code">
<pre class="brush:php;">
<?php
$keyword = 'PHP cURL';
//参数方法一
// $post = 'wd=' . urlencode($keyword);

//参数方法二
$post = array(
'wd' => 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_REFERER,$refer); //来路模拟
curl_setopt($ch,$post); //POST数据,$post可以是数组,也可以是拼接
$content = curl_exec($ch); //执行并存储结果
curl_close($ch);

var_dump($content);

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

//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,1); //返回数据不直接输出
$content = curl_exec($ch); //执行并存储结果
curl_close($ch);

echo $content;

四、需要cookie支持的采集

对于模拟登录的应用,单单提交参数和模拟来路并不能解决问题,这时候我们就需要保存或者提交相应的Cookie参数,这个在PHP cURL里面也提供了相应的参数: CURLOPT_COOKIE: 直接使用字符串方式提交cookie参数 CURLOPT_COOKIEFILE: 使用文件方式提交cookie参数 CURLOPT_COOKIEJAR: 保存提交后反馈的cookie数据

下面是PHP100的模拟登录示例:

<div class="jb51code">
<pre class="brush:php;">
<?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,$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_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压缩问题,下面是示例:

$ch = curl_init($url);
curl_setopt($ch,CURLOPT_ENCODING,"gzip"); //指定gzip压缩
$content = curl_exec($ch); //执行并存储结果
curl_close($ch);
echo $content;

手册说明:支持的编码有"identity","deflate"和"gzip"。如果为空字符串"",请求头会发送所有支持的编码类型。 后面一句表明,使用curl_setopt($ch,"");也是可以的,但是不能不加这个参数。

六、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参数禁用失败,所以大家最好同时使用两个参数。 下面是代码示例:

<div class="jb51code">
<pre class="brush:php;">
<?php
$searchStr = 'RC376981638HK';
$post = 'accion=LocalizaUno&numero='.$searchStr.'&ecorreo=&numeros=';

$url = 'https://aplicacionesweb.correos.es/localizadorenvios/track.asp';

$ch = curl_init($url); //初始化curl
curl_setopt($ch,1); //返回数据不直接输出
curl_setopt($ch,1); //发送POST类型数据
curl_setopt($ch,$post); //POST数据,$post可以是数组,也可以是拼接参数串
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); //SSL 报错时使用
curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); //SSL 报错时使用
$contents = curl_exec($ch); //执行并存储结果
// var_dump(curl_error($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 高匿代理

下面是代理采集示例:

<div class="jb51code">
<pre class="brush:php;">
<?php
$url = 'http://demo.zjmainstay.cn/php/curl/dump_ip.php?t=' . time();

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
curl_setopt($ch,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的一个简单示例:

<div class="jb51code">
<pre class="brush:php;">
<?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],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丢失而使得模拟登录失败,请求现象如图(六)所示:

关于CURLOPT_FOLLOWLOCATION,手册说明是:

启用时会将服务器服务器返回的"Location: "放在header中递归的返回给服务器,使用CURLOPT_MAXREDIRS可以限定递归返回的数量。 我个人理解,通俗点讲就是后面的跳转会继续跟踪访问,而且cookie在header里面被保留了下来。

十、模拟上传文件

在PHP手册的curl_setopt函数中,关于CURLOPT_POSTFIELDS有如下描述:

对于上传文件,这句话包含两个信息:

1. 要上传文件,post的数据参数必须使用数组,使得Content-Type头将会被设置成multipart/form-data。 2. 要上传文件,在文件名前面加上@前缀并使用完整路径。 因此,模拟文件上传可以按照如下实现:

'Foo','file' => '@d:/test.jpg');

$ch = curl_init('http://localhost/upload.php');
curl_setopt($ch,$data);
curl_exec($ch);

本地测试的时候,在upload.php文件中打印出和\$_FILES即可验证是否上传成功,如下: ```

输出结果类似:

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。

即:

'val1','param2' => 'val2',...));

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读8.4k次,点赞8次,收藏7次。SourceCodester Online Tours & Travels Management System pay.php sql injectionLine 16 of pay.php invokes a SQL query built using unvalidated input. This call could allow an attacker to modify the statement’s meaning or to execute arbitrary SQL commands.SQL
文章浏览阅读3.4k次,点赞46次,收藏51次。本文为大家介绍在windwos系统搭建typecho博客+cpolar内网穿透工具将博客发布到公共网络环境,实现远程也可以访问和操作。_windows搭建typecho
文章浏览阅读1.1k次。- php是最优秀, 最原生的模板语言, 替代语法,让php更加的优雅的与html生活在一起 -->请放心, 最终生成的,或者说用户最终看到的,仍然是一个html文档, php代码中的内容不会被泄漏的。-- 将php与html代码混编的时候,大括号很容易造成配对错误,最好杜绝它 -->php标签内部代码由php.exe解释, php标签之外的代码原样输出,仍由web服务器解析。-- 所以php的流程控制语句, 都提供了替代语法,用冒号代替大括号 -->php echo '百变鹏仔'?_利用php将静态页面修改为动态页面
文章浏览阅读1.1k次,点赞18次,收藏15次。整理K8s网络相关笔记博文内容涉及 Linux network namespace 认知以及彼此通信Demo,实际中的应用理解不足小伙伴帮忙指正不必太纠结于当下,也不必太忧虑未来,当你经历过一些事情的时候,眼前的风景已经和从前不一样了。——村上春树。_linux network namespace 多端通信 模式认知
文章浏览阅读1.2k次,点赞22次,收藏19次。此网络模型提供了一个逻辑二层(L2)网络,该网络封装在跨 Kubernetes 集群节点的现有三层(L3)网络拓扑上。使用此模型,可以为容器提供一个隔离的 L2 网络,而无需分发路由。封装网络带来了少量的处理开销以及由于覆盖封装生成 IP header 造成的 IP 包大小增加。封装信息由 Kubernetes worker 之间的 UDP 端口分发,交换如何访问 MAC 地址的网络控制平面信息。此类网络模型中常用的封装是 VXLAN、Internet 协议安全性 (IPSec) 和 IP-in-IP。_k8s网络组件对比
文章浏览阅读1.1k次,点赞14次,收藏19次。当我们谈论网络安全时,我们正在讨论的是保护我们的在线空间,这是我们所有人的共享责任。网络安全涉及保护我们的信息,防止被未经授权的人访问、披露、破坏或修改。
文章浏览阅读1.3w次,点赞3次,收藏7次。尽管您可以通过 ping 命令解析出网站的 IP 地址,但是可能在浏览器中访问时仍然遇到问题,这可能是因为浏览器使用的 DNS 解析结果不同于 ping 命令使用的解析结果。可能是因为您的网络或设备上设置了防火墙,阻止了对特定网站的访问。有些国家或组织可能会对特定的域名进行屏蔽,从而阻止访问相关网站。如果您的网络使用代理服务器进行访问控制,可能会由于代理服务器的配置问题导致无法访问某些网站。即使您的网络和设备一切正常,目标网站本身可能也存在问题,例如服务器故障、维护或过载,导致无法访问。_能ping通打不开网页
文章浏览阅读839次,点赞22次,收藏19次。本系统带文档lw万字以上文末可领取本课题的JAVA源码参考。
文章浏览阅读2.1k次,点赞31次,收藏22次。基于微信小程序奶茶点餐外卖系统设计与实现(PHP后台+Mysql)可行性分析毕设源代码毕业设计,数据安全和系统稳定性以及团队能力和资源配备方面都具备较好的条件。因此,该项目的可行性较高。:黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者,CSDN博客专家,在线教育专家,CSDN钻石讲师;微信小程序作为一种快捷、方便的移动应用形式,成为很多用户点餐外卖的首选。项目的界面和功能都可以定制,包安装运行!项目配有对应开发文档、开题报告、任务书、PPT、论文模版等。
文章浏览阅读1.8k次,点赞52次,收藏38次。本文主要通过对系统的前台系统和后台管理系统进行了功能性需求分析,对系统的安全性和可扩展性进行了非功能性需求分析。在详细的需求分析的基础上,根据系统的功能设计确定了数据库结构,实现完整的代码编写。Lucky+Baby母婴用品网站使用 Dreamweaver、HBuilder代码编辑器、Apache服务器等开发工具,完成了系统的主要模块的页面设计和功能实现。本文展示了首页页面的实现效果图,并通过代码和页面介绍了用户注册功能、商品搜索功能、生成订单和查看我的订单功能、在线付款功能功能的实现过程。
文章浏览阅读1.5k次,点赞45次,收藏40次。本设计主要实现集人性化、高效率、便捷等优点于一身的人事信息管理系统,完成首页、系统用户、通知公告、部门信息、员工薪资、考勤签到、员工请假、招聘信息、应聘信息等功能模块。
文章浏览阅读1k次。该错误通常出现在数据库读取结果集数据时,比如当我们写好SQL语句从数据库读取数据时,本身应该返回结果集,再给结果集中读取数据。解决思路:这种错误一般是因为echo后面输出了一个数组导致的,或者是数组作为字符串进行拼接运算时导致的。该错误直译为:警告:mysqli_fetch_assoc函数期望参数1是mysqli的结果集,但是给了一个布尔值。这种错误是PHP解析器在解析时遇到了语法错误,直译为:解析错误:语法错误,意料之外的...该错误直译为:提示:未定义的索引:username。_array to string conversion in
文章浏览阅读2.7w次。解决http请求报错context deadline exceeded (Client.Timeout exceeded while awaiting headers)_context deadline exceeded (client.timeout exceeded while awaiting headers)
文章浏览阅读1.3k次,点赞26次,收藏24次。复杂网络是一种由大量相互连接的元素(节点或顶点)组成的网络结构,这些连接通常是非常复杂和动态的。这些网络可以在各种领域中发现,包括社交网络、生物学系统、信息技术和交通系统等。_代理建模
文章浏览阅读2.6k次,点赞76次,收藏71次。epoll详解,事件模型,ET/LT模式,并通过三个示例进行代码实现。
文章浏览阅读3.3k次。罗拉ROLA-IP是一家来自纽约的代理IP提供商,由李嘉诚先生投资建设,韩国人工智能、自动驾驶、虚拟现实方面的领军企业World IT Show投资入股,由美国纽约大学IT管理教授团队研究开发,进入中国市场6年多,全世界设有多个分子公司。接下来,我们要检查代理和防火墙的设置,因为在绝大多数情况下,它们是导致这个错误的原因,尤其是当用户使用免费代理时。对网站的访问受阻实际上是一个非常常见的错误,它既可能是由于物理原因(硬件问题)造成的,也可能是由于软件错误引起的。检查代理设置,并确保其正确配置。_无法访问此网站,检查代理服务器和防火墙
文章浏览阅读1.1k次,点赞14次,收藏20次。本系统带文档lw万字以上文末可领取本课题的JAVA源码参考。_php洗车服务预约管理系统php源码
文章浏览阅读1.1k次。桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。同时,对于桶中元素的排序,选择何种比较排序算法对于性能的影响至关重要。
文章浏览阅读936次,点赞22次,收藏17次。本系统带文档lw万字以上文末可领取本课题的JAVA源码参考。
文章浏览阅读822次,点赞15次,收藏14次。在整个设计过程中,要确定可能的具体解决方案,以实现每一个小的最终目标,对于每一个小目标,我们首先必须了解一些相关的需求分析信息。除了以上作品下面是2023-2024年最新100套计算机专业原创的毕业设计源码+数据库,是近期作品,如果你的题目刚好在下面可以文末领取java源码参考。springboot基于springboot的在线考试系统。springboot基于springboot的商城购物系统。springboot基于微信小程序的智慧校园设计与实现。springboot基于用户的协同过滤算法的话题推荐。