手机版

基于PHP(小偷收集程序)的cURL快速入门教程

时间:2021-10-19 来源:互联网 编辑:宝哥软件园 浏览:

最棒的是,PHP还支持cURL库。本文将介绍cURL的一些高级特性以及如何在PHP中使用它。为什么要使用cURL?是的,我们可以通过其他方式获取网络内容。很多时候,因为想偷懒,直接用简单的PHP函数:$ content=file _ get _ contents('//www . jb51 . net ');//或$ lines=file('//www . JB 51 . net ');//orreadfile(//www . JB 51 . net);然而,这种做法缺乏灵活性和有效的错误处理。而且,你不能用它来完成一些困难的任务,比如处理coockies、验证、表单提交、文件上传等等。参考:cURL是一个功能强大的库,支持很多不同的协议和选项,可以提供各种与URL请求相关的细节。基本结构在学习更复杂的函数之前,我们先来看看在PHP中建立cURL请求的基本步骤:初始化设置变量执行并获取结果释放cURL句柄//1。初始化$ ch=curl _ init();//2.设置选项,包括URL curl _ setopt ($ ch,curl opt _ URL,'//www . JB 51 . net ');curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);curl_setopt($ch,CURLOPT_HEADER,0);//3.执行并获取HTML文档内容$ output=curl _ exec($ ch);//4.释放卷曲手柄curl _ close($ ch);第二步(即curl_setopt())是最重要的,所有的谜团都在这里。有一长串的cURL参数需要设置,可以指定URL请求的细节。可能很难一下子全部读懂,所以今天我们只尝试比较常见和有用的选项。检查错误您可以添加一个句子来检查错误(尽管这不是必需的)://.$ output=curl _ exec($ ch);if($ output===FALSE){ echo ' cURL error : '。curl _ error($ ch);}//.请注意,我们在比较时使用“==FALSE”而不是“==FALSE”。因为我们必须区分空输出和布尔值FALSE,后者才是真正的错误。获取信息这是另一个可选设置,可以在cURL执行后获取关于此请求的信息://.curl _ exec($ ch);$ info=curl _ getinfo($ ch);Echo' takes。$info['url']。$info['total_time']'秒';//.返回的数组包含以下信息:“URL”//资源网络地址“content _ type”//内容代码“http _ code”//http状态代码“header _ size”//header _ size”//请求大小“File time”//文件创建时间“SSL _ verify _ result”//SSL”//SSL验证结果“redirect _ count”//跳转技术“total _ time”//总时间“name lookup _ time”//DNS查询时间“connect _ time”/等待时间为“pretransfer _ time”//传输前准备时间为“size _ upload”//上传数据大小为“size _ download”//下载数据大小为“speed _ download”//下载速度为“speed _ upload”//上传速度为“download _ content _ length”//下载内容长度为“upload _ content _ length”//上传内容长度为“start transfer _ time”//开始传输时间为“redirect _ time”//重定向耗时基于浏览器的重定向在第一个示例中,我们将提供一个检测服务器是否有浏览器的代码例如,一些网站根据是否是移动浏览器甚至用户来自哪个国家来重定向网页。我们使用CURLOPT_HTTPHEADER选项来设置我们发送的HTTP头,包括用户代理信息和默认语言。然后让我们看看这些特定的网站是否会将我们重定向到不同的网址。

//测试用的URL $ URL=数组(' http://www。CNN。' com ',' http://www.mozilla.com ',' http://www。脸书。com’);//测试用的浏览器信息$ browsers=array(' standard '=array(' user _ agent '=' Mozilla/5.0(Windows;u;Windows NT 6.1美国;房车:1。9 .1 .6)Gecko/20091201火狐/3。5 .6(。 NET CLR 3.5.30729)',' language'='en-us,en;q=0.5 '),' iPhone '=array(' user _ agent '=' Mozilla/5.0(iPhone;u;像麦克操作系统这样的中央处理器;en)applebwebkit/420(KHML,像壁虎)版本/3.0 Mobile/1A537a Safari/419.3 ',' language'='en ',' French '=array(' user _ agent '=' Mozilla/4.0(兼容;MSIE 7.0Windows NT 5.1GTB6 . NET CLR 2.0.50727)',' language'='fr,FR-FR;q=0.5’);foreach($ URL as $ URL){ echo ' URL : $ URL \ n ';foreach($ browsers as $ test _ name=$ browser){ $ ch=curl _ init();//设置url curl_setopt($ch,CURLOPT_URL,$ URL);//设置浏览器的特定header curl_setopt($ch,CURLOPT_HTTPHEADER,array(' User-agent : { $ browser[' User _ agent ']} ',' Accept-language : { $ browser[' language ']} '));//页面内容我们并不需要curl_setopt($ch,CURLOPT _ NONE,1);//只需返回超文本传送协议头curl_setopt($ch,CURLOPT_HEADER,1);//返回结果,而不是输出它curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);$ output=curl _ exec($ ch);curl _ close($ ch);//有重定向的超文本传送协议头信息吗?if (preg_match('!位置:(。*)!',$output,$ matches)){ echo ' $ test _ name :重定向到$ matches[1]\ n;} else { echo '$test_name:无重定向\ n ';} }回显\ n \ n ';}首先,我们建立一组需要测试的网址,接着指定一组需要测试的浏览器信息。最后通过循环测试各种统一资源定位器和浏览器匹配可能产生的情况。因为我们指定了卷曲选项,所以返回的输出内容则只包括超文本传送协议头信息(被存放于$输出中)。利用一个简单的正则,我们检查这个头信息中是否包含了"位置: "字样。运行这段代码应该会返回如下结果

通过POST方法发送数据当一个GET请求被启动时,数据可以通过一个查询字符串被传递到一个URL。例如,在谷歌搜索时,搜索关键字是URL的查询字符串的一部分:http://www.google.com/search? Q=nettuts在这种情况下,您可能不需要cURL来模拟。您可以通过将此URL抛出到“file_get_contents()”来获得相同的结果。但是,有些HTML表单是通过POST方法提交的。提交此表单时,数据通过HTTP请求正文而不是查询字符串发送。比如在使用CodeIgniter论坛的形式时,不管你输入什么关键词,它总是会POST到下面的页面:http://codeigniter.com/forums/do_search/,你可以用PHP脚本来模拟这个URL请求。首先,创建一个可以接受和显示开机自检数据的新文件。我们将其命名为post _ output.php: print _ r ($ _ post)。接下来,编写一个PHP脚本来执行cURL请求:$ URL=' http://localhost/post _ output . PHP ';$post_data=array ('foo'='bar ',' query'='Nettuts ',' action '=' Submit ');$ ch=curl _ init();curl_setopt($ch,CURLOPT_URL,$ URL);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//我们是POST数据!curl_setopt($ch,CURLOPT_POST,1);//将curl _ setopt ($ ch,curl opt _ postfields,$ post _ data)添加到post的变量中;$ output=curl _ exec($ ch);curl _ close($ ch);echo $输出;执行代码后,您应该会得到以下结果:

这个脚本向post_output.php发送一个POST请求这个页面返回$_POST变量,我们使用cURL来捕获这个输出。上传文件上传文件与之前的POST非常相似。因为所有文件上传表单都是通过POST方法提交的。首先,创建一个接收文件的新页面,命名为upload _ output . PHP:print _ r($ _ files);下面是实际执行文件上传任务的脚本:$ URL=' http://localhost/upload _ output . PHP ';$ post _ data=array ('foo'=' bar ',//要上传的本地文件地址' upload '=' @ c :/wamp/www/test . zip ');$ ch=curl _ init();curl_setopt($ch,CURLOPT_URL,$ URL);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);curl_setopt($ch,CURLOPT_POST,1);curl_setopt($ch,CURLOPT_POSTFIELDS,$ post _ data);$ output=curl _ exec($ ch);curl _ close($ ch);echo $输出;如果需要上传文件,只需将文件路径作为post变量传递,但要记得在前面放上@符号。执行这个脚本应该会得到如下输出:

CURL批处理(multicrl)CURL还有一个高级功能——批处理句柄。此功能允许您同时或异步打开多个网址连接。下面是来自php.net的示例代码://创建两个cURL资源$ ch1=cURL _ init();$ CH2=curl _ init();//指定URL和适当的参数curl _ setopt ($ ch1,curl opt _ URL,' http://lxr . PHP . net/');curl_setopt($ch1,CURLOPT_HEADER,0);curl_setopt($ch2,CURLOPT_URL,' http://www . PHP . net/');curl_setopt($ch2,CURLOPT_HEADER,0);//创建CUlR批处理句柄$ MH=CUlR _ multi _ init();//添加前两个资源句柄curl_multi_add_handle($mh,$ ch1);curl_multi_add_handle($mh,$ CH2);//预定义一个状态变量$ active=null//执行批处理do {$ MRC=curl _ multi _ exec ($ MH,$ active);} while($ MRC==CURLM _ CALL _ MULTI _ PERFORM);while($ active $ MRC==CURLM _ OK){ if(curl _ multi _ select($ MH)!=-1){ do { $ MRC=curl _ multi _ exec($ MH,$ active);} while($ MRC==CURLM _ CALL _ MULTI _ PERFORM);} }//关闭每个句柄curl _ multi _ remove _ handle ($ MH,$ ch1);curl_multi_remove_handle($mh,$ CH2);curl _ multi _ close($ MH);我们在这里需要做的是打开多个cURL句柄,并将它们分配给一个批处理句柄。然后你只需要等待它在一段时间内完成循环。在这个例子中有两个主要的循环。第一个do-while循环重复调用curl_multi_exec()。这个函数是非阻塞的,但是会尽可能少的执行。它返回一个状态值,只要这个值等于常量curl _ call _ multi _ perform,就意味着还有一些紧急的工作要做(比如发送对应url的http头信息)。也就是说,我们需要连续调用函数,直到返回值发生变化。而下一个While循环仅在$active变量为真时继续。这个变量之前作为第二个参数传递给了curl_multi_exec(),这意味着只要批处理句柄中还有活动的连接。然后,我们调用curl_multi_select(),它被“屏蔽”直到活动连接(例如接收服务器响应)出现。成功执行此功能后,我们将进入另一个边做边循环,并继续下一个网址。让我们来看看如何将这个功能付诸实践:WordPress Connection Checker想象一下,你有一个博客,里面有大量的文章,这些文章包含大量指向外部网站的链接。过了一段时间,由于这样或那样的原因,相当多的链接失败了。要么是和谐要么是整个网站都上了功夫网.我们将在下面设置一个脚本,分析所有这些链接,找出无法打开或404的网站/页面,并生成报告。请注意,以下不是真正可用的WordPress插件,只是一个具有独立功能的脚本,仅供演示,谢谢。好了,我们开始吧。

首先,从数据库中读取所有这些链接://CONFIG $ db _ host=' localhost ';$ db _ user=“root”;$ db _ pass=$ db _ name=' WordPress $ excluded _ domain=array(' localhost ',' www。我的领地。com’);$ max _ connections=10/初始化一些变量$ URL _ list=array();$ working _ URL=array();$ dead _ URL=array();$ not _ found _ URL=array();$ active=null/连到MySQLif(!mysql_connect($db_host,$db_user,$db_pass)) { die('无法连接: '。MySQL _ error());}if(!mysql_select_db($db_name)) { die('无法选择db: ' .MySQL _ error());}//找出所有含有链接的文章$ q=' SELECT post _ content FROM WP _ post WHERE post _ content LIKE ' % href=% AND post _ status=' publish ' AND post _ type=' post ';$r=mysql_query($q)或die(MySQL _ error());while($ d=MySQL _ fetch _ assoc($ r)){//用正则匹配链接if (preg_match_all('!href=\ '(.*?)\'!$d['post_content'],$matches)) { foreach ($matches[1]为$url) { //排除某些域$ tmp=parse _ URL($ URL);if (in_array($tmp['host'],$ excluded _ domain)){ continue;} //存储URL $ URL _ list[]=$ URL;} }}//移除重复链接$ URL _ list=array _ values(array _ unique($ URL _ list));if(!$url_list) { die('没有要检查的URL ');}我们首先配置好数据库,一系列要排除的域名($ excluded _ domains),以及最大并发连接数($max_connections)。然后,连接数据库,获取文章和包含的链接,把它们收集到一个数组中($url_list)。下面的代码有点复杂了,因此我将一小步一小步地详细解释://1.批处理器$ MH=curl _ multi _ init();//2.加入需批量处理的($ I=0)的URL$ I $ max _ connections $ I){ add _ URL _ to _ multi _ handle($ MH,$ URL _ list);}//3.初始处理do { $mrc=curl_multi_exec($mh,$ active);} while($ MRC==CURLM _ CALL _ MULTI _ PERFORM);//4.主循环而($active $mrc==CURLM_OK) { //5 .有活动连接if (curl_multi_select($mh)!=-1) { //6.干活do { $mrc=curl_multi_exec($mh,$ active);} while($ MRC==CURLM _ CALL _ MULTI _ PERFORM);//7.有信息否?if($ mhinfo=curl _ multi _ info _ read($ MH)){//意味着该连接正常结束//8.从卷曲句柄获取信息$ chinfo=curl _ getinfo($ mhinfo[' handle ']);//9.死链么?if(!$ chinfo[' http _ code ']){ $ dead _ URL[]=$ chinfo[' URL '];//10.404了?} else if($ chinfo[' http _ code ']==404){ $ not _ found _ URL[]=$ chinfo[' URL '];//11.还能用} else { $ working _ URL[]=$ chinfo[' URL '];} //12.移除句柄curl_multi_remove_handle($mh,$ mhinfo[' handle ']);curl _ close($ mhinfo[' handle ']);//13.加入新网址,干活if (add_url_to_multi_handle($mh,$ URL _ list)){ do { $ MRC=curl _ multi _ exec($ MH,$ active);} while($ MRC==CURLM _ CALL _ MULTI _ PERFORM);} } }}//14.完了curl _ multi _ close($ MH);echo '==死URL==\ n ';回声内爆(' \n ',$ dead _ urls).\ n \ n ';echo '==404个URLs==\ n回声内爆(' \n ',$ not _ found _ urls).\ n \ n ';echo '==工作URL==\ n ';回声内爆(' \n ',$ working _ URL//15。向批处理器添加URL函数add _ URL _ to _ multi _ handle($ MH,$ URL _ list){ static $ index=0;//如果还剩全球资源定位器(统一资源定位符)没用if ($url_list[$index]) { //新建卷曲句柄$ ch=curl _ init();//配置url curl_setopt($ch,CURLOPT_URL,$ URL _ list[$ index]);//不想输出返回的内容curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//重定向到哪儿我们就去哪儿curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1);//不需要内容体,能够节约带宽和时间curl_setopt($ch,CURLOPT _ NONE,1);//加入到批处理器中curl_multi_add_handle($mh,$ ch);//拨一下计数器,下次调用该函数就能添加下一个全球资源定位器(统一资源定位符)了$索引返回真;} else { //没有新的统一资源定位器需要处理了返回false}}下面解释一下以上代码。列表的序号对应着代码注释中的顺序数字。新建一个批处理器创建了一个多手柄。稍后我们将创建一个把统一资源定位器加入批处理器的函数add_url_to_multi_handle()。每当这个函数被调用,就有一个新全球资源定位器(统一资源定位符)被加入批处理器。

首先,我们向批处理程序添加了10个URL(这个数字由$max_connections决定)。运行curl_multi_exec()进行初始化是必要的,只要它返回curl _ call _ multi _,就还有工作要做。这样做的主要原因是创建连接,它不会等待完整的URL响应。只要批处理中有活动的连接,主循环就会继续。Curl_multi_select()将等到url查询产生活动连接。CURL的工作又来了,主要是获取响应数据。查各种资料。当URL请求完成时,将返回一个数组。返回的数组中有一个cURL句柄。我们使用它来获取单个cURL请求的相应信息。如果这是一个死链或者请求超时,http状态代码将不会被返回。如果缺少此页面,将返回状态代码404。在其他情况下,我们都认为这个链接是可用的(当然,你也可以检查500个错误等等)。从该批中删除此cURL句柄,因为它不再有用,请关闭它!很好,现在可以添加另一个网址了。初始化工作再次开始.嗯,所有需要做的都已经做了。关闭批处理程序并生成报告。回顾一下向批处理程序添加新网址的功能。每次调用这个函数时,静态变量$index都会递增,这样我们就可以知道还有多少URL需要处理。我在我的博客上运行了一次这个脚本(为了测试,故意添加了一些错误的链接),结果如下:img border=' 0 ' src=' http://img.cppcns.com/pic.php? URL=/upload/20110602225008534 . png '/检查了大约40个URL,不到两秒钟。当你需要查更大数量的网址时,可以想象省心省力的效果!如果同时打开10个连接,可以快上10倍!此外,您还可以使用cURL批处理的非阻塞功能来处理大量的URL请求,而不会阻塞您的Web脚本。其他有用的cURL选项http身份验证如果URL请求需要基于HTTP的身份验证,可以使用以下代码:将内容复制到剪贴板代码: $ URL=' http://www . somesite.com/members/';$ ch=curl _ init();curl_setopt($ch,CURLOPT_URL,$ URL);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//发送用户名和密码curl _ setopt ($ ch,curl opt _ userpwd,'我的用户名3360我的密码');//可以允许它重定向curl _ setopt ($ ch,curl opt _ followlocation,1);//以下选项允许cURL在重定向后发送用户名和密码curl _ setopt ($ ch,cURL opt _ unlimited _ auth,1)/;$ output=curl _ exec($ ch);curl _ close($ ch);用FTP类库上传PHP,但也可以用curl://打开一个文件指针$file=fopen('/path/to/file ',' r ');//url包含大部分必需信息$ URL=' FTP ://username 3360[email protected]:21/path/to/new/file ';$ ch=curl _ init();curl_setopt($ch,CURLOPT_URL,$ URL);curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//上传相关选项curl _ setopt ($ ch,curl opt _ upload,1);curl_setopt($ch,CURLOPT_INFILE,$ FP);curl_setopt($ch,CURLOPT_INFILESIZE,file size('/path/to/file '));//是否开启ASCII模式(上传文本文件时有用)curl _ setopt ($ ch,curl opt _ FTP ASCII,1);$ output=curl _ exec($ ch);curl _ close($ ch);您可以使用代理启动CUlR请求:$ ch=CUlR _ init();curl_setopt($ch,CURLOPT_URL,' http://www . example.com ');curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//指定代理地址curl _ setopt ($ ch,curl opt _ proxy,' 11 . 11 . 1133608080 ');//如有必要,请提供用户名和密码curl _ setopt ($ ch,curl opt _ proxy userpwd,' user 3360 pass ');$ output=curl _ exec($ ch);curl _ close($ ch);回调函数可以让cURL在URL请求过程中调用指定的回调函数。例如,在下载内容或响应的过程中,应该立即使用数据,而不是等到完全下载。

$ ch=curl _ init();curl_setopt($ch,CURLOPT_URL,' http://net . tutplus.com ');curl_setopt($ch,CURLOPT_WRITEFUNCTION,' progress _ function ');curl _ exec($ ch);curl _ close($ ch);function progress_function($ch,$ str){ echo $ str;return strlen($ str);}此回调函数必须返回字符串的长度,否则此函数将无法正常工作。在接收URL响应的过程中,每当收到数据包时都会调用这个函数。总结今天,我们学习了cURL库强大的功能和灵活的可扩展性。希望你喜欢。下次你发起一个网址请求时,考虑一下cURL!原文:基于PHP的快速入门英语原文:http://net.tutsplus.com/tutorial.for-mastering-curl/原作者:Burak Guzel。

版权声明:基于PHP(小偷收集程序)的cURL快速入门教程是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。