php集合工件cURL用法的详细说明
对做过数据收集的人来说,CURL并不陌生。PHP中虽然有一个file_get_contents函数可以获取远程链接的数据,但是它的可控性太差,对于各种复杂的采集场景,file_get_contents似乎有点力不从心。因此,本文将向您介绍集合工件cURL的使用。
首先补充一下file_get_contents函数可以获取远程链接数据的方法。
?PHP $ URL=' http://git . oschina . net/罗云/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 $通知;这段代码将直接使用curl来显示文件的内容,但是问题来了,因为curl是php的扩展,为了安全起见,有些主机会使用curl。在宁外本地调试php的时候,curl也是关闭的,所以会出现错误,所以这段代码不可取,所以刘芸重写了。
?PHP if(function _ exists(' curl _ init '){ $ URL=' http://git . oschina . net/罗云/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);$ dxy content=curl _ exec($ ch);echo $ dxycontent} else {echo '汗水!您的服务器好像还没有打开curl扩展,所以无法收到云洛的通知。请联系主机公司打开,请忽略本地调试。}?修改后的版本是判断curl扩展,看服务器是否打开了curl扩展。如果打开,会直接显示文件,如果没有打开,会显示提示文本。虽然问题已经解决,但还有一个问题。我只是展示一段文字,并不是用什么去做大事。那么我为什么要写这么多代码呢?经过一些测试,发现file_get_contents在获取远程文件的内容方面并不比curl慢,在一些文件很少的情况下可能比curl扩展要快很多,所以我重写了代码。
?PHP echo file _ get _ contents(' http://git . oschina . net/罗云/API/raw/master/notice . txt ');工具火狐firebug“如果你想做好一件事,你必须先磨尖你的工具。”在分析案例之前,让我们学习如何使用工件Firebug来获取必要的信息。使用F12打开Firebug,我们可以得到如图(1)所示的界面:
1.箭头图标是一个“元素选择”工具。单击后,图标将突出显示。同时,当鼠标在页面内移动时,相应的内容会在HTML菜单中被选中。此时,点击内容意味着元素被选中,图标的高亮显示将被取消。如图(2)所示:Firebug视图元素。
2.控制台JS中console.log系列函数的打印在这里输出。3.HTMLHTML内容。请注意,您在这里看到的不一定是要收集和分析的内容。收集时,对内容的分析总是基于查看源代码(Ctrl U)。在这里,您可以快速定位元素的结构,然后选择一个特殊的引用来定位源代码中的相应位置。例如,您在HTML中看到一个标签,它是div id=' demo ' class=' demo ' demo/div,但是当您检查源代码时看到的可能是div class=' demo ' id=' demo ' demo/div。如果按照前者对收集到的内容做常规匹配,是得不到结果的。4.CSS这里是CSS文件5的内容。脚本这里是Javascript文件6的内容。DOM节点7的内容。收集并分析网络中每个请求链路的数据。它可以显示每个请求的参数、请求头和Cookie数据。如果页面提交将被刷新,则需要使用hold,这样页面请求内容在刷新后会保留在控制台中,如图(3)所示:
此外,火狐有一个篡改数据扩展,也可以获取请求的数据,必要时可以安装使用。8.CookiesCookie数据。
在图(1)中,我们还可以看到下面有许多可选的小菜单项,其中保持是我们关心的。选择时,即使提交表单刷新页面,后续内容区域的数据仍会保留,这对于分析提交的数据尤为关键。
综上所述,在分析采集请求时,我们主要关心的是“网络”菜单中的请求数据。如有必要,使用“保持”查看刷新页面的请求数据。在请求之前,我们可以先使用“清除”来清除以下内容。
案例分析一、简单集合这里的简单集合是指单个页面GET请求的集合,非常简单,即使通过file_get_contents函数也可以很容易地得到页面返回结果。
代码片段的file_get_contents。
?PHP $ URL=' http://demo . ZJ中流砥柱. cn/PHP/curl/simple . html ';$ content=file _ get _ contents($ URL);echo $内容;代码片段的CURL
?PHP $ URL=' http://demo . ZJ中流砥柱. cn/PHP/curl/simple . html ';$ ch=curl _ init($ URL);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//返回的数据不直接输出$ content=curl _ exec($ ch);//执行并存储结果curl _ close($ ch);echo $内容;其次,在参数收集的情况下,页面请求需要传入一些参数,可以是GET请求,也可以是POST请求。这种情况的获取仍然可以通过使用带有一些参数的file_get_contents来实现,但是这里我们就不展示了。
对于代码片段的cURL GET的请求,我们可以选择搜索引擎作为示范。比如我在百度搜索一个词“PHP cURL”,输入回车后,我们会得到一个类似的http://www.baidu.com/s? IE=UTF-8F=8RSV _ BP=1ch=TN=百度条=WD=PHP curl。请注意,这里的链接在不同的浏览器和不同的进入方式访问时可能会得到不同的结果,所以不要担心链接是否相同。通过输入多个关键字并观察链接,我们可以确定wd参数是我们想要传入的动态参数,而其他参数可以不变,因此我们得到以下采集代码。
?php $关键字=' PHP cURL$url='http://www.baidu.com/s?ie=utf-8f=8rsv _ BP=1ch=TN=Baidu bar=wd='。urlencode($关键字);$ ch=curl _ init($ URL);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//返回的数据不直接输出$ content=curl _ exec($ ch);//执行并存储结果curl _ close($ ch);echo $内容;有时候,有些参数是不必要的。这时,我们可以删除它。比如上面的链接只能保留http://www.baidu.com/s? ie=utf-8wd=PHP cURL,Ie=utf-8可能会影响结果的编码,所以暂时保留吧。有了这个简单的代码,我们就可以收集百度搜索的结果。
我们在代码片段的cURL POST中请求POST类型并不少见。例如,有些搜索是通过POST提交的,所以我们需要通过POST类型提交参数。这个PHP cURL中有对应的参数:CURLOPT_POST和CURLOPT _ POSTFIELDS。CURLOPT_POST的设置可以指定当前提交是否处于POST模式,而CURLOPT_POSTFIELDS用于设置提交参数,可以是参数字符串,也可以是参数数组,例如:
curl_setopt($ch,CURLOPT_POSTFIELDS,' ie=utf-8wd=PHP cURL ');或者curl _ setopt ($ ch,curl opt _ postfields,array ('ie'=' utf-8 ',' wd'=' PHP curl ',));下面是一个POST模拟搜索PHP POST搜索。后端使用之前的百度关键词搜索。基本原理是客户端向我的服务器提交一个关键词,我的服务器用这个关键词请求百度搜索,然后得到结果返回给客户端。如图(4)所示,我们使用Firebug来分析请求数据,并获得我们需要提交的请求链接和请求参数:
然后是我们的代码:
?php $关键字=' PHP CUlR//参数方法一//$post='wd=' .urlencode($关键字);//参数方法二$ post=array(' wd '=URL encode($ keyword),);$ URL=' http://演示。ZJ中流砥柱。cn/PHP/curl/search。PHP ';$ ch=curl _ init($ URL);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//返回数据不直接输出curl_setopt($ch,CURLOPT_POST,1);//发送邮政类型数据curl_setopt($ch,CURLOPT_POSTFIELDS,$ post);//POST数据,$post可以是数组,也可以是拼接$ content=curl _ exec($ ch);//执行并存储结果curl _ close($ ch);var _ dump($ content);三、需要推荐人的采集对于一些程序,它可能判断来源网址,如果发现推荐人不是自己的网站,则拒绝访问,这时候,我们就需要添加CURLOPT _ REFERER参数,模拟来路,使得程序能够正常采集。
?php $关键字=' PHP CUlR//参数方法一//$post='wd=' .urlencode($关键字);//参数方法二$ post=array(' wd '=URL encode($ keyword),);$ URL=' http://演示。ZJ中流砥柱。cn/PHP/curl/search _ refer。PHP ';$ refer=' http://demo。ZJ中流砥柱。cn/';//来路地址$ 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);//POST数据,$post可以是数组,也可以是拼接$ content=curl _ exec($ ch);//执行并存储结果curl _ close($ ch);var _ dump($ content);search_refer.php的源码如下,做了简单的推荐人判断拦截:
?php if(空($ _ POST[' wd ']){ exit('拒绝空参数。');}//推荐人判断if(剥离OS($ _ SERVER[' HTTP _ REFER '],$ _ SERVER[' HTTP _ HOST '])==false){ exit(' Deny ');} $ keyword=添加斜线(trim(strip _ tags($ _ POST[' wd '])));$ URL='http://www.baidu.com/s?ie=utf-8wd=' .urlencode($关键字);$ ch=curl _ init($ URL);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//返回数据不直接输出$ content=curl _ exec($ ch);//执行并存储结果curl _ close($ ch);回声$内容;四、需要甜饼干支持的采集对于模拟登录的应用,单单提交参数和模拟来路并不能解决问题,这时候我们就需要保存或者提交相应的饼干参数,这个在PHP cURL里面也提供了相应的参数:CURLOPT_COOKIE:直接使用字符串方式提交甜饼干参数CURLOPT_COOKIEFILE:使用文件方式提交甜饼干参数CURLOPT_COOKIEJAR:保存提交后反馈的甜饼干数据
下面是PHP100的模拟登录示例:
?服务器端编程语言(Professional Hypertext Preprocessor的缩写)标题(' content-type : text/html;字符集=UTF-8 ';$cookie_file=tempnam(' ./temp ',' cookie ');$ log in _ URL=' http://BBS。PHP 100。com/登录。PHP ';$ post _ fields=' CK时间=36000 step=2pwuser=usernamepwpwd=password ';//提交登录表单请求$ ch=curl _ init($ log in _ 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 rol _ setopt($ ch,CURLOPT_COOKIEJAR,$ COOKIE _ file);//存储提交后得到的甜饼干数据curl _ exec($ ch);curl _ close($ ch);//登录成功后,获取论坛首页数据$ URL=' http://BBS。PHP 100。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 _编码都无法还原数据,然后又没有概念,各种抓狂却找不到方法,哈哈,我曾经也是这样~如图(五)是乱码表现形式:
幸运的是,最终自助者找到了,这就是CURLOPT_ENCODING参数。比如在收集搜狐新闻的时候,我们遇到了gzip压缩的问题。这里有一个例子:
?PHP $ URL=' http://news . Sohu.com/';$ ch=curl _ init($ URL);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//不要直接输出curl _ setopt ($ ch,curl opt _ encoding,' gzip ');//指定gzip压缩$ content=curl _ exec($ ch);//执行并存储结果curl _ close($ ch);echo $内容;手动描述:支持的代码有' identity ',' deflate '和' gzip '。如果是空字符串“”,请求头将发送所有支持的编码类型。后一句表示使用了curl _ setopt ($ ch,curl opt _ encoding ' ');也是可以的,但是不能添加这个参数。
不及物动词SSL链接的集合一些请求的链接是https类型的,所以使用cURL的集合可能会失败。此时,我们可以使用var_dump(curl_error($ch))。方法打印错误提示,然后根据错误提示找到相应的解决方案。SSL错误的常见提示,例如:SSL证书问题:无法获取本地颁发者证书,此时,我们需要使用参数:CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST来禁用SSL证书的验证。我尝试过只通过使用CURLOPT_SSL_VERIFYPEER参数来禁用失败,所以最好同时使用这两个参数。下面是一个代码示例:
?php $ searchStr=' RC376981638HK$ post=' accion=localizaunonomero='。$searchStr。ecorreo=numeros=';$ URL=' https://aplicacioneweb . correaos . es/localizadorenvios/track . ASP ';$ ch=curl _ init($ URL);//初始化curl curl _ setopt ($ ch,curl opt _ returntransfer,1);//返回的数据不直接输出curl_setopt($ch,CURLOPT_POST,1);//发送POST类型数据curl _ setopt ($ ch,curl opt _ postfields,$ POST);//POST数据,$post可以是数组或串联参数字符串curl _ setopt ($ ch,curl opt _ SSL _ verifypeer,false);//当SSL报告错误时,使用curl _ setopt ($ ch,curl opt _ SSL _ verifyhost,false);//当//SSL报告错误时,使用$ contents=curl _ exec($ ch);//执行并存储结果//var _ dump(curl _ error($ ch));//采集失败是使用(采集错误提示)curl _ close($ ch);echo $ contents7.特工集合众所周知,中国有恶墙。因此,如果我们需要获取墙上的一些数据,我们需要使用国外的代理服务器。或者当我们需要收集大量数据时,需要不断切换IP,我们也会用到代理。PHP cURL中使用的代理有几个对应的参数:CURLOPT_PROXY、CURLOPT_PROXYPORT和CURLOPT _ PROXYUSERPWD,还有其他几个,这里不一一列举。CURLOPT_PROXY指定代理IP参数CURLOPT_PROXYPORT指定代理端口参数CURLOPT _ PROXYUSERPWD指定要验证的代理的帐户密码,以及格式为“[username]:[password]”的字符串。
至于代理账号获取,我们自己玩吧。这里我提供了一个在线搜索列表:cURL高隐藏代理。
以下是代理集合的示例:
?PHP $ URL=' http://demo . ZJ中流砥柱. cn/php/curl/dump_ip.php?t='。time();回显“本地IP”:' file _ get _ contents ($ URL)。'\ n获取IP:“;$ IP=' 183 . 224 . 1 . 116 ';$ port=' 80//伪造请求头参数。如果是高级代理,则不需要提供$ header=array(' x-forward-for : '。$ IP,“客户端-ip:”。$ IP,$ ch=curl _ init($ URL);//初始化curl curl _ setopt ($ ch,curl opt _ 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 $内容;八、多线程采集对于大量的采集工作,为了提高采集效率,使用PHP cURL提供多线程采集是必不可少的。手册中提供的多线程集合示例似乎都不太容易使用。我从一开始就测试了它的几个例子,但是发现它们都卡在执行中,根本无法完成。前几天突然又测试了一遍,然后发现curl_multi_info_read函数下的示例#1是可执行的,内容在$res上,但是没有打印出来。此外,雅虎的请求缓慢而停滞,前两个链接都可以。然而,幸运的是,当时的例子并不容易使用。然后,在搜索之后,我发现了一个强大的项目cURL Multi,它将PHP cURL Multi封装在一个良性的扩展中,提供了很好的集合支持。我就不介绍CurlMulti的用法了。官方网站提供了演示。如果使用过程中有技术问题,可以直接加入Q群讨论。作者@阿瑞斯等收藏公牛将提供技术解决方案。下面是PHP cURL Multi的一个简单例子:
?PHP $ URL=array(' http://demo . ZJ中流砥柱. cn/php/curl/curl_multi_1.php ',' http://demo . ZJ中流砥柱. cn/php/curl/curl_multi_2.php ',);$ MH=curl _ multi _ init();foreach($ URL 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);如果(假的!==$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);9.302 Jump (301 Jump)对于某些应用程序,例如模拟登录,如果遇到302 Jump,cookie将丢失,模拟登录将失败。请求现象如图(6)所示:
此时,您可以使用:
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);关于CURLOPT_FOLLOWLOCATION,手册解释道:
启用时,服务器返回的“Location:”将在头中递归返回给服务器,递归返回的数量可以通过使用CURLOPT_MAXREDIRS来限制。我个人理解,以一种流行的方式,下面的跳转将继续跟踪访问,cookie保留在头中。
X.在PHP手册的curl_setopt函数中模拟上传文件,CURLOPT_POSTFIELDS描述如下:
所有数据都是使用HTTP协议中的“开机自检”操作发送的。要发送文件,请在文件名前加上@前缀,并使用完整路径。此参数可以通过类似“para1=val1para2=val2 .”的字符串传递在urlencoded之后,或者使用以字段名作为键值,以字段数据作为值的数组。如果值是数组,内容类型头将设置为多部分/表单数据。对于上传文件,这句话包含两条信息:
1.要上传文件,post的数据参数必须使用数组,这样Content-Type头将被设置为multipart/form-data。2.要上传文件,请在文件名前加上@前缀,并使用完整路径。因此,模拟文件上传可以实现如下:
//上传D盘下的test.jpg文件,文件必须存在,否则卷曲处理失败且没有任何提示$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]=应用程序/八位字节-流[tmp _ name]=d : \ xampp \ tmp \ php2ea 0。tmp[错误]=0[大小]=139999))关于CURLOPT_POSTFIELDS的赋值,另外补充一句描述:传递一个数组到CURLOPT_POSTFIELDS,cURL会把数据编码成多部分/表单数据,而然传递一个网址编码字符串时,数据会被编码成应用程序/x-www-form-urlencoded。
即:
curl_setopt(\(ch,CURLOPT_POSTFIELDS,' param1=val1param2=val2.));和curl_setopt(\)ch,CURLOPT_POSTFIELDS,数组(' param1'='val1 ',' param2'='val2 ',));这样一个功能强大的采集神器卷曲的使用方法为大家介绍到这,希望对大家的学习有所帮助。
版权声明:php集合工件cURL用法的详细说明是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。