您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
php超大数组的分组算法及tp5命令行实现分组携程抓取并存储数据于数据库(多个command的实现)
发布时间:2022-06-10 21:52:16编辑:雪饮阅读()
SeedProductManagement.php:
<?php
namespace app\home\command;
use think\facade\App;
use think\console\Command;
use think\console\Input;
use think\console\Output;
use think\Db;
use think\Env;
use function Swoole\Coroutine\run;
use function Swoole\Coroutine\go;
use Swoole\Coroutine\Channel;
class SeedProductManagement extends Command
{
protected function configure()
{
$this->setName('SeedProductManagement')->setDescription('种子产品管理');
}
public static function executeGroup2($group){
//执行分组
$len=count($group);
$chan = new Channel($len);
$host='cha.191.cn';
for($i=1;$i<=$len;$i++){
go(function () use ($chan,$i,$host,$group) {
$cli = new \Swoole\Coroutine\Http\Client($host, 443,true);
$cli->set(['timeout' => 10]);
$cli->setHeaders([
'Host' => $host,
"User-Agent" => 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36',
'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding' => 'gzip, deflate, br',
]);
$token="8194277bbb57b042107e812c0a1dfe06b48859dd1654823766465";
$url='/api3/product/detailInfo?des=3cecQI03vqoM%2FVP2LyGwpN%2FXlI0WrUC9eSmmhvkHXMpX%2FSk4vNI1jJNW1lfxGA&product_id='.$group[$i-1].'&device_id=HKL59YKE&version=2.4.0&sys=android&token='.$token.'&deviceId=HKL59YKE&channleId=';
$cli->get($url);
$body=$cli->body;
if(!$body){
$body="empty";
}
$key="k_".$i;
$val=$body;
$chan->push([$key=>$val]);
});
}
for ($i = 1; $i <=$len; $i++)
{
$current_result=$chan->pop();
$keys=array_keys($current_result);
$json_to_arr=json_decode($current_result[$keys[0]],true);
// file_put_contents("meta_data_".$group[$i-1],var_export($json_to_arr,true));
//var_dump("000000000000000");
if(isset($json_to_arr["data"]) && isset($json_to_arr["data"]["info"]) && isset($json_to_arr['data']['info']['id'])){
//var_dump("1111111111");
$info=$json_to_arr['data']['info'];
$dir_path=ROOT_PATH."/mission_meta";
if(!is_dir($dir_path)){
mkdir($dir_path);
}
$log_file_name="meta_data_".$group[$i-1];
file_put_contents($dir_path."/".$log_file_name,var_export($json_to_arr,true));
$insert = [
//测试id
'test_id' => $info['id'],
//审定编号
'approval_no' => $info['registry'],
//作物种类
'crop_species' => $info['name'],
//品种名称
'name' => $info['product_name'],
//企业ID
'seed_enterprise_id' => $info['company_id'],
//审定单位
'approved_country' => isset($info['auditing_body']) ? $info['auditing_body']:'',
//审定年份
'year' => isset($info['register_year']) ? $info['register_year']:'',
//品种来源
'source' => isset($info['source']) ? $info['source']:'',
//是否转基因
'is_transgene' => isset($info['gmo']) ? $info['gmo']:'否',
// 特征特性
'features' => isset($info['features']) ? $info['features']:'',
//产量表现
'performance' => isset($info['yield']) ? $info['yield']:'',
//适宜区域
'suitable_area' => isset($info['suitable_range']) ? $info['suitable_range']:'',
//实验情况
'experimental_situation' => isset($info['experiments']) ? $info['experiments']:'',
//创建时间
'createtime' => time(),
//更新时间
'updatetime' => time(),
// 权重
'weigh' => rand(1, 9999),
'status' => 'normal',
];
$count=Db::name('fa_seed_product')->where('test_id',$info['id'])->count();
if($count==0){
Db::name('fa_seed_product')->insert($insert);
}
else{
$dir_path=ROOT_PATH."/mission_exist";
if(!is_dir($dir_path)){
mkdir($dir_path);
}
$log_file_name="meta_data_".$group[$i-1];
file_put_contents($dir_path."/".$log_file_name,var_export($json_to_arr,true));
}
}
else{
//var_dump("2222222");
$dir_path=ROOT_PATH."/mission_failed";
if(!is_dir($dir_path)){
mkdir($dir_path);
}
$log_file_name="meta_data_".$group[$i-1];
file_put_contents($dir_path."/".$log_file_name,var_export($json_to_arr,true));
}
var_dump("------gao".$group[$i-1]."执行完成");
if($i==$len){
//var_dump("分组".($group_index+1)."执行完成");
return true;
}
}
}
protected function execute(Input $input, Output $output)
{
//分组
$total_rows=500000;
//分组大小,分组大小越大越接近 "Too many open files"错误的触发
/*
*
*
*
在这个文件vim /etc/security/limits.conf末尾加上"* - nofile 8192"
最前的 * 表示所有用户,可根据需要设置某一用户,例如
user1 soft nofile 8192
user1 hard nofile 8192
注意”nofile”项有两个可能的限制措施。就是项下的hard和soft。 要使修改过得最大打开文件数生效,必须对这两种限制进行设定。 如果使用”-“字符设定, 则hard和soft设定会同时被设定。
*
*
* */
$groups_size=8000;
$group_num=ceil($total_rows/$groups_size);
$groups=[];
for($i=1;$i<=$group_num;$i++){
$last_id=0;
$last_group_index=count($groups)-1;
if($last_group_index>-1){
$last_group_data_index=count($groups[$last_group_index])-1;
$last_id=$groups[$last_group_index][$last_group_data_index];
}
$really_group_size=$groups_size;
if($i==$group_num){
$really_group_size=$total_rows-$groups_size*($i-1);
}
$cureent_group=[];
for($x=1;$x<=$really_group_size;$x++){
$cureent_group[]=$last_id+$x;
}
$groups[]=$cureent_group;
}
//分组完成
\Swoole\Coroutine\run(function() use($groups){
$len=count($groups);
for($i=1;$i<=$len;$i++){
$group=$groups[$i-1];
var_dump("分组".$i."开始执行");
$res=Self::executeGroup2($group);
var_dump("分组".$i."执行完成");
}
});
}
}
这里需要注意的是那个self是必须的,如果用类名就会发现当你将这个脚本拷贝第二份时候这里类名如果忘了修改,则你运行的是第二个命令,但是执行的却是之前那个命令里面的例如这里的executeGroup2了。我就在这里被坑了大概有10多分钟。。。。
关键字词:php,分组,算法,数组,tp5,命令行,多个command