php多线程抓取信息测试例子

PHP 5.3 以上版本,使用pthreads PHP扩展,可以使PHP真正地支持多线程。多线程在处理重复性的循环任务,能够大大缩短程序执行时间。
PHP扩展下载:https://github.com/krakjoe/pthreads
PHP手册文档:http://php.net/manual/zh/book.pthreads.php
1、扩展的编译安装(Linux),编辑参数 --enable-maintainer-zts 是必选项:
cd /Data/tgz/php-5.3.8
./configure --prefix=/Data/apps/php --with-config-file-path=/Data/apps/php/etc --with-mysql=/Data/apps/mysql --with-mysqli=/Data/apps/mysql/bin/mysql_config --with-iconv-dir --with-freetype-dir=/Data/apps/libs --with-jpeg-dir=/Data/apps/libs --with-png-dir=/Data/apps/libs --with-zlib --with-libxml-dir=/usr --enable-xml --disable-rpath --enable-bcmath --enable-shmop --enable-sysvsem --enable-inline-optimization --with-curl --enable-mbregex --enable-fpm --enable-mbstring --with-mcrypt=/Data/apps/libs --with-gd --enable-gd-native-ttf --with-openssl --with-mhash --enable-pcntl --enable-sockets --with-xmlrpc --enable-zip --enable-soap --enable-opcache --with-pdo-mysql --enable-maintainer-zts
make clean
make
make install unzip pthreads-master.zip
cd pthreads-master
/Data/apps/php/bin/phpize
./configure --with-php-config=/Data/apps/php/bin/php-config
make
make install
添加扩展: vi /Data/apps/php/etc/php.ini
extension = "pthreads.so"
一段PHP多线程、与For循环,抓取百度搜索页面的PHP代码示例:
代码如下 复制代码
<?php
class test_thread_run extends Thread
{
public $url;
public $data; public function __construct($url)
{
$this->url = $url;
} public function run()
{
if(($url = $this->url))
{
$this->data = model_http_curl_get($url);
}
}
} function model_thread_result_get($urls_array)
{
foreach ($urls_array as $key => $value)
{
$thread_array[$key] = new test_thread_run($value["url"]);
$thread_array[$key]->start();
} foreach ($thread_array as $thread_array_key => $thread_array_value)
{
while($thread_array[$thread_array_key]->isRunning())
{
usleep(10);
}
if($thread_array[$thread_array_key]->join())
{
$variable_data[$thread_array_key] = $thread_array[$thread_array_key]->data;
}
}
return $variable_data;
} function model_http_curl_get($url,$userAgent="")
{
$userAgent = $userAgent ? $userAgent : 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2)';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, 5);
curl_setopt($curl, CURLOPT_USERAGENT, $userAgent);
$result = curl_exec($curl);
curl_close($curl);
return $result;
} for ($i=0; $i < 100; $i++)
{
$urls_array[] = array("name" => "baidu", "url" => "http://www.baidu.com/s?wd=".mt_rand(10000,20000));
} $t = microtime(true);
$result = model_thread_result_get($urls_array);
$e = microtime(true);
echo "多线程:".($e-$t)."n"; $t = microtime(true);
foreach ($urls_array as $key => $value)
{
$result_new[$key] = model_http_curl_get($value["url"]);
}
$e = microtime(true);
echo "For循环:".($e-$t)."n";
?>
例子,采集数据 代码如下 复制代码
<?php
$urls = array(
'http://www.111cn.net/',
'http://www.sohu.com/',
'http://www.163.com/'
);
$save_to='/test.txt'; // 把抓取的代码写入该文件
$st = fopen($save_to,"a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER ,0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT,60);
curl_setopt($conn[$i],CURLOPT_RETURNTRANSFER,true); // 设置不将爬取代码写到浏览器,而是转化为字符串
curl_multi_add_handle ($mh,$conn[$i]);
}
do {
curl_multi_exec($mh,$active);
} while ($active);
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]); // 获得爬取的代码字符串
fwrite($st,$data); // 将字符串写入文件。当然,也可以不写入文件,比如存入数据库
} // 获得数据变量,并写入文件
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh,$conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($st);
?> 出于对算法对于系统的影响的好奇,决定实验性的在实际生产环境中研究一下算法对系统效率的影响。二分法最重要的是对有序数据的查询定位,例如手机号码就是一个很贴切的有序排列的数据例子。
如果数据量很小,例如只有10条有序数据,要查询其中的第9条数据,轮询查询需要查询9次确定结果,二分法查询次数为3次(分别是匹配第5、8、9条记录)即可确定结果。数据量越大,二分法所带来的效率就是程2的阶乘递增,可以大大提升服务器的运行效率、提升用户等待时间、节省服务器资源。
实验环境:LAMP
实验数据:国内手机号码归属地。手机号码前7位代表一个号段,生成从1300000到1590000之间的所有号段按从小到大排列,大约30万条数据。
传统查询:对于任意手机号码,截取前7位,从数据库中第一条记录开始循环向下匹配,如果对照,则返回查询结果。
代码如下 复制代码
flock($fp,LOCK_SH);
$note = fread($fp,filesize('./data.php')); //读取数据
fclose($fp);
$note = explode("n",$note);
array_pop($note);
array_shift($note);
$num = count($note);
$_data = '';
//循环查询开始
for($i=1;$i<$num;$i++){
$row = explode(" ",$note[$i]);
if($m == $row[0]){
$_data = $row;
break;
}
}
实测结果:最快0.03512秒、最慢0.63043秒、平均查询用时约为0.4秒。
二分法查询:对于任意手机号码,截取前7位。首先匹配数据库中最中间的第100000条数据,根据二分法原则,若匹配结果比中间值大,重新选择第二次匹配第100000到200000的中间值----第150000条数据。以此类推,直到查询到最后一位正确的值返回结果。那么每次的查询次数小于或等于17次。
代码如下 复制代码
flock($fp,LOCK_SH);
$note = fread($fp,filesize('./data.php')); //读取数据
fclose($fp);
$note = explode("n",$note);
array_pop($note);
array_shift($note);
$num = count($note); //统计数据库总记录数
$_data = '';
$low = 0; //二分法两端点变量
$hight = $num;
while($m < 1599999){
$num = ceil(($hight + $low)/2);
$row = explode(" ",$note[$num]);
if ($m == $row[0]){
return $_data = $row;
break;
}else{
$m >= $row[0] ? $low = $num : $hight = $num;
}
}
实测结果:每次查询都在0.034—0.035之间。
结论:本试验可以看出,二分法数据查询效率比传统效率快10倍以上。本实验数据只有30万条,在普通的应用性数据查询时,数据量越大,越能显示出二分法的优越性(理论上讲,上千万的数据查询次数不超过30次便可准确定位),在更大量的数据的时候,查询效率或许能真的给人直观的反应。 效果如下
提交
代码如下 复制代码
index.php文件
php结合jquery异步上传图片(ajaxSubmit),以下为提交页面代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Ajax异步上传图片</title>
<script src="js/jquery-1.4.2.js" language="JavaScript" type="text/javascript"></script>
<script src="js/jquery.form.js" language="JavaScript" type="text/javascript"></script>
<script type="text/javascript">
function sky_upfiles(){
var messtxt;
$("#sky_upform").ajaxSubmit({
//dataType:'script',
type:'post',
url: "doupfiles.php",
beforeSubmit: function(){
$("#sky_txt").html("图片上传中...");
},
success: function(data){
if(data=="1"){
messtxt = "上传成功!";
}else if(data=="-1"){
messtxt = "文件超过规定大小!";
}else if(data=="-2"){
messtxt = "文件类型不符!";
}else if(data=="-3"){
messtxt = "移动文件出错!";
}else{
messtxt = "未知错误!";
}
$("#sky_txt").html(messtxt);
//$("#sky_txt").append(data);
},
resetForm: false,
clearForm: false
});
//$("#upimgform").submit();
}
</script>
</head>
<body>
<br />
<fieldset style="width:97%">
<legend>上传文件</legend>
<form enctype="multipart/form-data" id="sky_upform" name="sky_upform" action="" method="post">
<table width="100%" border="0" align="center" cellpadding="3" cellspacing="0">
<tr>
<td width="100" align="right" class="f-12"></td>
<td class="f-12" align="left">
<input name="upfile" id="upfile" maxlength="20" size="40" type="file" value="" /><input name="upmit" type="button" id="upmit" value="上传" onclick="sky_upfiles()"/>
<font color="red" id="sky_txt"></font></td>
</tr>
</form> </body>
</html>
doupfiles.php文件
代码如下 复制代码
<?php
/*
* 1:成功上传
*-1:文件超过规定大小
*-2:文件类型不符
*-3:移动文件出错
*/
if(is_uploaded_file($_FILES['upfile']['tmp_name'])){
$photo_types=array('image/jpg', 'image/jpeg','image/png','image/pjpeg','image/gif','image/bmp','image/x-png');//定义上传格式
$max_size=700000; //上传照片大小限制,默认700k
$photo_folder="upload/".date("Y")."/".date("m")."/".date("d")."/"; //上传照片路径
///////////////////////////////////////////////////开始处理上传
if(!file_exists($photo_folder))//检查照片目录是否存在
{
mkdir($photo_folder, 0777, true); //mkdir("temp/sub, 0777, true);
}
$upfile=$_FILES['upfile'];
$name=$upfile['name'];
$type=$upfile['type'];
$size=$upfile['size'];
$tmp_name=$upfile['tmp_name'];
$file = $_FILES["upfile"];
$photo_name=$file["tmp_name"];
//echo $photo_name;
$photo_size = getimagesize($photo_name);
if($max_size < $file["size"])//检查文件大小
echo "-1"; //echo "<script>alert('对不起,文件超过规定大小!');history.go(-1);</script>";
if(!in_array($file["type"], $photo_types))//检查文件类型
echo "-2"; //echo "<script>alert('对不起,文件类型不符!');history.go(-1);</script>";
if(!file_exists($photo_folder))//照片目录
mkdir($photo_folder);
$pinfo=pathinfo($file["name"]);
$photo_type=$pinfo['extension'];//上传文件扩展名
$photo_server_folder = $photo_folder.time().".".$photo_type;//以当前时间和7位随机数作为文件名,这里是上传的完整路径 if(!move_uploaded_file ($photo_name, $photo_server_folder))
{
echo "-3"; //echo "移动文件出错";
exit;
}
$pinfo=pathinfo($photo_server_folder);
$fname=$pinfo['basename'];
echo "1"; //echo " 已经成功上传:".$photo_server_folder."<br />"; }
?>
最后把完整的php+jquery Ajax异步上传图片(ajaxSubmit)实例源码下载地址

  

php多线程抓取信息测试例子的更多相关文章

  1. PHP利用Curl实现多线程抓取网页和下载文件

    PHP 利用 Curl  可以完成各种传送文件操作,比如模拟浏览器发送GET,POST请求等等,然而因为php语言本身不支持多线程,所以开发爬虫程序效率并不高,一般采集 数据可以利用 PHPquery ...

  2. scrapy-splash抓取动态数据例子八

    一.介绍 本例子用scrapy-splash抓取界面网站给定关键字抓取咨询信息. 给定关键字:个性化:融合:电视 抓取信息内如下: 1.资讯标题 2.资讯链接 3.资讯时间 4.资讯来源 二.网站信息 ...

  3. scrapy-splash抓取动态数据例子七

    一.介绍 本例子用scrapy-splash抓取36氪网站给定关键字抓取咨询信息. 给定关键字:个性化:融合:电视 抓取信息内如下: 1.资讯标题 2.资讯链接 3.资讯时间 4.资讯来源 二.网站信 ...

  4. scrapy-splash抓取动态数据例子六

    一.介绍 本例子用scrapy-splash抓取中广互联网站给定关键字抓取咨询信息. 给定关键字:打通:融合:电视 抓取信息内如下: 1.资讯标题 2.资讯链接 3.资讯时间 4.资讯来源 二.网站信 ...

  5. scrapy-splash抓取动态数据例子五

    一.介绍 本例子用scrapy-splash抓取智能电视网网站给定关键字抓取咨询信息. 给定关键字:打通:融合:电视 抓取信息内如下: 1.资讯标题 2.资讯链接 3.资讯时间 4.资讯来源 二.网站 ...

  6. scrapy-splash抓取动态数据例子四

    一.介绍 本例子用scrapy-splash抓取微众圈网站给定关键字抓取咨询信息. 给定关键字:打通:融合:电视 抓取信息内如下: 1.资讯标题 2.资讯链接 3.资讯时间 4.资讯来源 二.网站信息 ...

  7. scrapy-splash抓取动态数据例子三

    一.介绍 本例子用scrapy-splash抓取今日头条网站给定关键字抓取咨询信息. 给定关键字:打通:融合:电视 抓取信息内如下: 1.资讯标题 2.资讯链接 3.资讯时间 4.资讯来源 二.网站信 ...

  8. scrapy-splash抓取动态数据例子二

    一.介绍 本例子用scrapy-splash抓取一点资讯网站给定关键字抓取咨询信息. 给定关键字:打通:融合:电视 抓取信息内如下: 1.资讯标题 2.资讯链接 3.资讯时间 4.资讯来源 二.网站信 ...

  9. scrapy-splash抓取动态数据例子十六

    一.介绍 本例子用scrapy-splash爬取梅花网(http://www.meihua.info/a/list/today)的资讯信息,输入给定关键字抓取微信资讯信息. 给定关键字:数字:融合:电 ...

随机推荐

  1. yourphp内置编辑器

    {: $Form->editor(array(')),$vo[desc])} form.php 如: <tr> <td>机器故障:</td> <td&g ...

  2. asp.net webform中使用async,await实现异步操作

    摘要 最近想着将项目中的部分耗时的操作,进行异步化.就自己弄个demo进行学习.只需下面几个步骤就可以将aspx页面中注册异步操作. demo 比如我们需要抓取某个url的内容,这个时候我们可能会有下 ...

  3. 深入浅出JMS(一)--JMS基本概念

     from:http://blog.csdn.net/jiuqiyuliang/article/details/46701559 深入浅出JMS(一)--JMS基本概念 标签: jmsmessagin ...

  4. NetBeans使用习惯:升级与保存配置

    如何升级:点击 netbeans 的升级更新 ,即可升级版本:不推荐官网下载进行安装,否则会出现,以前的旧版本8.0的目录和8.0.1目录,虽然它会自动检测到以前版本的配置,提示导入... 如何备份: ...

  5. sql是如何执行一个查询的!

    引用自:http://rusanu.com/2013/08/01/understanding-how-sql-server-executes-a-query/ Understanding how SQ ...

  6. 基础知识系列☞各版本下IIS请求处理过程区别

    转载地址→http://www.cnblogs.com/fsjohnhuang/articles/2332074.html ASP.NET是一个非常强大的构建Web应用的平台, 它提供了极大的灵活性和 ...

  7. iOS之下拉放大,上推缩小,一个方法搞定

    先来看看效果吧. 讲讲大概的实现思路:1、创建头部的视图和tableview,需要注意的是tableview要设置contentInset,contentInsent 的顶部要和头部视图的背景图的高度 ...

  8. Java多线程初学者指南(7):向线程传递数据的三种方法

    在传统的同步开发模式下,当我们调用一个函数时,通过这个函数的参数将数据传入,并通过这个函数的返回值来返回最终的计算结果.但在多线程的异步开发模式下,数据的传递和返回和同步开发模式有很大的区别.由于线程 ...

  9. nyoj 14 会场安排问题(贪心专题)

    会场安排问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4   描述 学校的小礼堂每天都会有许多活动,有时间这些活动的计划时间会发生冲突,需要选择出一些活动进行举办.小刘的工 ...

  10. 采用Atlas+Keepalived实现MySQL读写分离、读负载均衡【转载】

      文章 原始出处 :http://sofar.blog.51cto.com/353572/1601552 ============================================== ...