用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中模拟并发请求,自然是很方便的,只要多开几个线程,发起请求就好了.但是,这种请求, ...
随机推荐
- [转]JS组件系列——Bootstrap组件福利篇:几款好用的组件推荐
本文转自:https://www.cnblogs.com/landeanfen/p/5461849.html#_label3 阅读目录 一.时间组件 1.效果展示 2.源码说明 3.代码示例 二.自增 ...
- git入门(廖雪峰老师)
根据廖雪峰老师的git教程进行学习总结: 1.之前上班用的都是svn进行管理,那么svn和git有什么区别呢? svn是集中式的版本控制系统,而git是分布式版本控制系统,那么集中式和分布式版本控制系 ...
- Spring Security之Remember me详解
Remember me功能就是勾选"记住我"后,一次登录,后面在有效期内免登录. 先看具体配置: pom文件: <dependency> <groupId> ...
- C# 取得上月月头和月尾、上周的第一天和最后一天。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- blfs(systemv版本)学习笔记-总页
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! lfs(systemv版本)学习笔记:https://www.cnblogs.com/renren-study-notes/p/ ...
- oracle数据库相关概念介绍
数据库相关概念介绍: 问题: 数据存储:变量(基本类型,引用类型) 基本类型:少量数据 引用类型:保证数据的完整性 数据源: 声明直接赋值 IO流从硬盘中读取 java在处理数据时,需要从硬盘中读取数 ...
- javascript: checked 不可全选
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 【20190129】CSS-定位问题记录
很多情况下我在写div的时候都不会把高度写死,而是用子元素撑开高度的方式,但是如果子元素设置了浮动或者position绝对定位,就相当于把子元素从文档流中拿出来了,这时父元素的高度就不能被子元素撑开了 ...
- CSS中的sprites
CSS的sprites(雪碧图,精灵图) *三个名字都要记住 定义:就是将界面上需要的小的导航按钮图标,小图标整合成一张背景图片 然后用background-position来实现背 ...
- AWT初步—Frame和 Panel
初识 AWT GUI 和 AWT GUI:Graphics User Interface 图形用户界面 AWT:Abstract Window Toolkit 抽象窗口工具集 之前的程 ...