用PHP的curl实现并发请求远程文件(并发抓取远程网页)
PHP的curl功能确实强大了。里面有个curl_multi_init功能,就是批量处理任务。可以利用此,实现多进程同步抓取多条记录,优化普通的网页抓取程序。
一个简单的抓取函数:
function http_get_multi($urls){
$count = count($urls);
$data = [];
$chs = [];
// 创建批处理cURL句柄
$mh = curl_multi_init();
// 创建cURL资源
for($i = 0; $i < $count; $i ++){
$chs[ $i ] = curl_init();
// 设置URL和相应的选项
curl_setopt($chs[ $i ], CURLOPT_RETURNTRANSFER, 1); // return don't print
curl_setopt($chs[ $i ], CURLOPT_URL, $urls[$i]);
curl_setopt($chs[ $i ], CURLOPT_HEADER, 0);
curl_multi_add_handle($mh, $chs[ $i ]);
}
// 增加句柄
// for($i = 0; $i < $count; $i ++){
// curl_multi_add_handle($mh, $chs[ $i ]);
// }
// 执行批处理句柄
do {
$mrc = curl_multi_exec($mh, $active);
} while ($active > 0);
while ($active and $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
for($i = 0; $i < $count; $i ++){
$content = curl_multi_getcontent($chs[ $i ]);
$data[ $i ] = ( curl_errno($chs[ $i ]) == 0 ) ? $content : false;
}
// 关闭全部句柄
for($i = 0; $i < $count; $i ++){
curl_multi_remove_handle($mh, $chs[ $i ]);
}
curl_multi_close($mh);
return $data;
}
下面的调用测试(get()函数如这里: http://www.cnblogs.com/whatmiss/p/7114954.html):
//弄很多个网页的url
$url = [
'http://www.baidu.com',
'http://www.163.com',
'http://www.sina.com.cn',
'http://www.qq.com',
'http://www.sohu.com',
'http://www.douban.com',
'http://www.cnblogs.com',
'http://www.taobao.com',
'http://www.php.net',
];
$urls = [];
for($i = 0; $i < 10; $i ++){
foreach($url as $r)
$urls[] = $r . '/?v=' . rand();
} //并发请求
$datas = http_get_multi($urls);
foreach($datas as $key => $data){
file_put_contents('log/multi_' . $key . '.txt', $data); // 记录一下请求结果。记得创建一个log文件夹
}
$t2 = microtime(true);
echo $t2 - $t1;
echo '<br />'; //同步请求, get()函数如这里: http://www.cnblogs.com/whatmiss/p/7114954.html$t1 = microtime(true);
foreach($urls as $key => $url){
file_put_contents('log/get_' . $key . '.txt', get($url)); // 记录一下请求结果。记得创建一个log文件夹
}
$t2 = microtime(true);
echo $t2 - $t1;
测试结果,很明显的差距,而且随着数据量越大,会呈指数级的拉大差距:
2.4481401443481
21.68923997879 8.925509929657
24.73141503334 3.243185043335
23.384337902069 3.2841880321503
24.754415035248 3.2091829776764
29.068662881851
参考,感谢原作者:
http://php.net/manual/zh/function.curl-multi-init.php
http://www.tuicool.com/articles/auiEBb
http://blog.csdn.net/liylboy/article/details/39669963 此文写了可能超时的问题
另,这里有一篇文章说,多线程并不会更快,甚至还稍慢一点点,我觉得很奇怪,怎么会有这样的结果:
http://www.webkaka.com/tutorial/php/2013/102843/
用PHP的curl实现并发请求远程文件(并发抓取远程网页)的更多相关文章
- linux 服务发布脚本升级,远程发布,指定拉取远程dev,test等分支代码
1.本地发布脚本 publish.sh #!/bin/sh currentDay=`date +%Y%m%d` currentTime=`date +%Y%m%d%H%M%S` tomcat1=/da ...
- Linux远程自动输入密码抓取远程资源
#!/usr/bin/expect -fset timeout 3000set sys_date [lindex $argv 0] #要抓取的文件日期spawn scp /data3/xiaorui/ ...
- Tomcat如何使用线程池处理远程并发请求
Tomcat如何使用线程池处理远程并发请求 通过了解学习tomcat如何处理并发请求,了解到线程池,锁,队列,unsafe类,下面的主要代码来自 java-jre: sun.misc.Unsafe j ...
- 如何配置IIS处理多并发请求及存在的问题
很多时候多线程能快速高效独立的计算数据,应用比较多. 但今天遇到的多进程下的问题更是让人觉得复杂 多进程下static变量都要失效,就目前的平台和产品static使用是很多的,各种session.ca ...
- 使用CURL下载远程文件保存到服务器
比如微信公众平台开发,下载用户的头像到服务器上: /** * 使用CURL获取远程文件保存到服务器 *@param $image=$oJSON->headimgurl; 获取到的微信返回的头像U ...
- Rolling cURL: PHP并发最佳实践
Rolling cURL: PHP并发最佳实践 在实际项目或者自己编写小工具(比如新闻聚合,商品价格监控,比价)的过程中, 通常需要从第3方网站或者API接口获取数据, 在需要处理1个URL队列时, ...
- PHP学习笔记,curl,file_get_content,include和fopen四种方法获取远程文件速度测试.
这几天在做抓取.发现用PHP的file_get_contents函数来获取远程文件的过程中总是出现失败,并且效率很低下.所以就做了个测试的demo来测试下PHP中各种方法获取文件的速度. 程序里面使用 ...
- php curl模拟post请求提交数据样例总结
在php中要模拟post请求数据提交我们会使用到curl函数,以下我来给大家举几个curl模拟post请求提交数据样例有须要的朋友可參考參考.注意:curl函数在php中默认是不被支持的,假设须要使用 ...
- java中如何模拟真正的同时并发请求?
有时需要测试一下某个功能的并发性能,又不要想借助于其他工具,索性就自己的开发语言,来一个并发请求就最方便了. java中模拟并发请求,自然是很方便的,只要多开几个线程,发起请求就好了.但是,这种请求, ...
随机推荐
- 使用gitlab, jenkins搭建CI(持续集成)系统(3) -- 根据不同触发条件执行不同的构建任务
前面在jenkins中安装的gitlab hook支持不同的参数,具体可以参考gitlab hook文档https://github.com/jenkinsci/gitlab-hook-plugin# ...
- functions文件详细分析和说明
bash&shell系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html /etc/rc.d/init.d/functions几乎被/e ...
- Ado.net和EF的区别
ado.net EF作为微软的一个ORM框架,通过实体.关系型数据库表之间的映射,使开发人员可以通过操作表实体而间接的操作数据库,大大的提高了开发效率.这样一来,.net平台下,我们与底层数据库的交互 ...
- oracle sql优化的几种方法
1.最基本最简单的方式是减少访问数据库的次数.oracle在内部执行了许多工作,比如解析SQL语句, 估算索引的利用率, 读数据块等等,都将大量耗费oracle数据库的运行 2.选择最有效率的表名顺 ...
- 自定义基于jquery竖向瀑布流插件
公司新项目做了一个关于图片的板块,网上找了一些瀑布流插件都不是很适合自己,于是就自己造轮子写一个,并封装成插件github 于是就想分享一下,主要是为了更好的学习与记忆. 如果大家进来了,希望能给我g ...
- HTML常用标签及属性
标签格式 格式: 双边:<标签名 属性1="值1" 属性2='值2' 属性3=值3>内容</标签名> 单边:<标签名 属性1="值1&quo ...
- 【代码笔记】Web-HTML-基础
一,效果图. 二,代码. <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...
- K-Means算法的10个有趣用例
https://www.jianshu.com/p/162c9ec713cf 摘要: 让我们走进K-Means算法的“前世今生”以及和它有关的十个有趣的应用案例. K-means算法具有悠久的历史,并 ...
- Sqlserver精简安装选项
- recovery 升级过程LED灯闪烁
Android设备在进入recovery升级的过程,我们在屏幕上面可以看到升级的机器人动画,以及升级的进度显示.这仅限于有屏幕的设备,比如平板PAD,电视TV等,对与没有屏幕的盒子BOX,那么在不接入 ...