作者 刘锟

update

  1 +<?php
  2 +
  3 +namespace App\Console\Commands\Inquiry;
  4 +
  5 +use App\Models\Inquiry\InquiryInfo;
  6 +use App\Models\Inquiry\InquiryProject;
  7 +use App\Models\Inquiry\InquiryRelayDetail;
  8 +use App\Models\Inquiry\InquiryRelayDetailLog;
  9 +use Illuminate\Console\Command;
  10 +use Illuminate\Support\Facades\Cache;
  11 +use Illuminate\Support\Facades\Http;
  12 +use Illuminate\Support\Facades\Log;
  13 +use Illuminate\Support\Facades\Redis;
  14 +
  15 +/**
  16 + * Class postInquiry
  17 + * @package App\Console\Commands\Inquiry
  18 + */
  19 +class PostInquiryForward extends Command
  20 +{
  21 + /**
  22 + * The name and signature of the console command.
  23 + *
  24 + * @var string
  25 + */
  26 + protected $signature = 'post_inquiry_forward';
  27 +
  28 + /**
  29 + * The console command description.
  30 + *
  31 + * @var string
  32 + */
  33 + protected $description = '执行询盘请求';
  34 +
  35 + /**
  36 + * Create a new command instance.
  37 + *
  38 + * @return void
  39 + */
  40 + public function __construct()
  41 + {
  42 + parent::__construct();
  43 + }
  44 +
  45 +
  46 + public function handle()
  47 + {
  48 + while (true) {
  49 + $list = InquiryRelayDetailLog::where('status', InquiryRelayDetailLog::STATUS_INIT)->where('start_at', '<=', date('Y-m-d H:i:s'))->orderBy('id', 'asc')->limit(100)->get();
  50 + if (!$list->count()) {
  51 + sleep(1);
  52 + }
  53 + // 询盘数据入库
  54 + foreach ($list as $key => $val) {
  55 + //加个锁 避免重复执行
  56 + $lockKey = 'inquiry_relay_detail_log_lock_' . $val->id;
  57 + if (!Redis::setnx($lockKey, 1)) {
  58 + continue;
  59 + }
  60 + Redis::expire($lockKey, 60);
  61 +
  62 + $log = InquiryRelayDetailLog::find($val->id);
  63 + if ($log->status != InquiryRelayDetailLog::STATUS_INIT) {
  64 + continue;
  65 + }
  66 +
  67 + $this->output('开始执行' . $val->id);
  68 + try {
  69 + $detail = InquiryRelayDetail::find($val['detail_id']);
  70 +
  71 + //防止 程序中断 启动时 同一时间一下就发了
  72 + $last_log = InquiryRelayDetailLog::where('detail_id', $val['detail_id'])->where('id', '<', $val['id'])->orderBy('id', 'desc')->first();
  73 + //不是第一个 或者 上一个处理失败了 直接处理
  74 + if (!empty($last_log)) {
  75 + //上一个还没有处理 直接跳过
  76 + if ($last_log->status == InquiryRelayDetailLog::STATUS_INIT) {
  77 + continue;
  78 + }
  79 + //上一个处理完成
  80 + if ($last_log->status == InquiryRelayDetailLog::STATUS_SUCCESS) {
  81 + //上次处理时间间隔达到没
  82 + $interval = strtotime($val->start_at) - strtotime($last_log->start_at);
  83 + if (time() - strtotime($last_log->updated_at) < $interval) {
  84 + continue;
  85 + }
  86 + }
  87 + }
  88 +
  89 + if ($val['type'] == 1) {
  90 + $this->visit($detail, $val);
  91 + } else {
  92 + $res = $this->inquiry($detail, $val);
  93 +
  94 + //转发表单
  95 + if ($res) {
  96 + $form = InquiryInfo::find($detail['form_id']);
  97 + $form->success = $form->success + 1;
  98 + $form->save();
  99 + Log::channel('inquiry_forward')->info('询盘成功:', [$detail['form_id'], $val->id, getmypid()]);
  100 + }
  101 + }
  102 + } catch (\Exception $e) {
  103 + Log::channel('inquiry_forward')->error('post_inquiry_forward handle error', [$e->getMessage(), $e->getFile(), $e->getLine()]);
  104 +
  105 + $val->status = InquiryRelayDetailLog::STATUS_FAIL;
  106 + $val->remark = mb_substr($e->getMessage(), 0, 200);
  107 + $val->save();
  108 + }
  109 + }
  110 + }
  111 + }
  112 +
  113 + public function visit(InquiryRelayDetail $detail, InquiryRelayDetailLog $log)
  114 + {
  115 + $website = $detail['website'];
  116 + if ($detail['is_v6']) {
  117 + $data = [
  118 + 'ip' => $detail['ip'],
  119 + 'url' => $log['url'],
  120 + 'device_port' => $detail['device_port'],
  121 + 'referrer_url' => $detail['referrer'],
  122 + 'user_agent' => $detail['user_agent'],
  123 + ];
  124 + $res = Http::withoutVerifying()->timeout(30)->post($website . 'api/traffic_visit/', $data)->json();
  125 + if (empty($res['status']) || $res['status'] != 200) {
  126 + $log->status = InquiryRelayDetailLog::STATUS_FAIL;
  127 + $log->remark = mb_substr($res['message'] ?? '', 0, 200);
  128 + $log->save();
  129 +
  130 + Log::channel('inquiry_forward')->error('post_inquiry_forward visit error', [$res, $website . 'api/traffic_visit/', $data]);
  131 + return false;
  132 + }
  133 + } else {
  134 + //v4 v5分离项目 往测试链接推
  135 + $project_info = InquiryProject::select(['is_split', 'test_domain'])->where('domain', $website)->first();
  136 + if (!$project_info) {
  137 + $log->status = InquiryRelayDetailLog::STATUS_FAIL;
  138 + $log->remark = '获取域名对应项目失败';
  139 + $log->save();
  140 +
  141 + return false;
  142 + }
  143 +
  144 + if ($project_info['is_split'] == 1) {
  145 + $website = $project_info['test_domain'];
  146 + }
  147 +
  148 + $data = [
  149 + 'action' => 'stats_init',
  150 + 'assort' => 0,
  151 + 'referrer' => $detail['referrer'],
  152 + 'currweb' => $log['url'],
  153 + 'user_agent' => $detail['user_agent'],
  154 + "ip" => $detail['ip'],
  155 + ];
  156 + $res = Http::get($website . 'wp-admin/admin-ajax.php', $data);
  157 + $status = $res->status();
  158 + if ($status != 200) {
  159 + $log->status = InquiryRelayDetailLog::STATUS_FAIL;
  160 + $log->remark = mb_substr($res->body() ?? '', 0, 200);
  161 + $log->save();
  162 +
  163 + Log::channel('inquiry_forward')->error('post_inquiry_forward v4|v5 visit error', [$res->body(), $website . 'wp-admin/admin-ajax.php', $data]);
  164 + return false;
  165 + }
  166 + }
  167 + $log->status = InquiryRelayDetailLog::STATUS_SUCCESS;
  168 + $log->save();
  169 + return true;
  170 + }
  171 +
  172 + public function inquiry(InquiryRelayDetail $detail, InquiryRelayDetailLog $log)
  173 + {
  174 + // v6
  175 + if ($detail['is_v6']) {
  176 + $res = $this->v6Inquiry($detail, $log);
  177 + } else {
  178 + $res = $this->v5Inquiry($detail, $log);
  179 + }
  180 +
  181 + if (!$res) {
  182 + return false;
  183 + }
  184 +
  185 + $log->status = InquiryRelayDetailLog::STATUS_SUCCESS;
  186 + $log->save();
  187 +
  188 + return true;
  189 + }
  190 +
  191 + public function v6Inquiry($detail, $log)
  192 + {
  193 + $website = $detail['website'];
  194 + $data = [
  195 + 'name' => $detail['name'],
  196 + 'phone' => $detail['phone'],
  197 + 'message' => $detail['message'],
  198 + 'submit_ip' => $detail['ip'],
  199 + 'refer' => $log['url'],
  200 + ];
  201 + if ($detail['email']) {
  202 + $data['email'] = $detail['email'];
  203 + } else {
  204 + $data['__amp_source_origin'] = trim($website, '/');
  205 + }
  206 + $res = Http::withoutVerifying()->timeout(30)->withHeaders(['User-Agent' => $detail['user_agent']])->post($website . 'api/inquiryQd?source=5', $data)->json();
  207 + if (empty($res['code']) || $res['code'] != 200) {
  208 + $log->status = InquiryRelayDetailLog::STATUS_FAIL;
  209 + $log->remark = mb_substr($res['message'] ?? '', 0, 200);
  210 + $log->save();
  211 + Log::channel('inquiry_forward')->error('post_inquiry_forward v6 inquiry error', [$res, $website . 'api/inquiryQd/', $data]);
  212 + return false;
  213 + }
  214 + return true;
  215 + }
  216 +
  217 + public function v5Inquiry($detail, $log)
  218 + {
  219 + $data = [
  220 + 'name' => $detail['name'],
  221 + 'phone' => $detail['phone'],
  222 + 'message' => $detail['message'],
  223 + 'email' => $detail['email'],
  224 + 'ip' => $detail['ip'],
  225 + 'token' => md5($log['url'] . $detail['name'] . $detail['ip'] . date("Y-m-d")),
  226 + 'refer' => $log['url'],
  227 + 'submit_time' => date('Y-m-d H:i:s'),
  228 + 'source' => 5,
  229 + ];
  230 +
  231 + $result = Http::withoutVerifying()->timeout(30)->post('https://www.globalso.site/api/external-interface/add/fa043f9cbec6b38f', $data);
  232 + $res['data'][0]['status'] = 'success';
  233 + //兼容接口返回格式
  234 + if (!empty($res['data'][0]['status'])) {
  235 + $res['data'][0]['code'] = $res['data'][0]['status'] == 'success' ? 200 : 400;
  236 + !empty($res['data'][0]['msg']) && $res['message'] = $res['data'][0]['msg'];
  237 + }
  238 + if (empty($res['data'][0]['code']) || !in_array($res['data'][0]['code'], [200, 300])) {
  239 + $log->status = InquiryRelayDetailLog::STATUS_FAIL;
  240 + $log->remark = mb_substr($res['message'] ?? '', 0, 200);
  241 + $log->save();
  242 +
  243 + Log::channel('inquiry_forward')->error('post_inquiry_forward v4|v5 inquiry error', [$result->body(), 'https://www.globalso.site/api/external-interface/add/fa043f9cbec6b38f', $data]);
  244 + return false;
  245 + }
  246 + return true;
  247 + }
  248 +
  249 +
  250 + public function output($message)
  251 + {
  252 + echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
  253 + }
  254 +}
  1 +<?php
  2 +/**
  3 + * Created by PhpStorm.
  4 + * User: akun
  5 + * Date: 2025/02/24
  6 + * Time: 14:14
  7 + */
  8 +
  9 +namespace App\Console\Commands\Inquiry;
  10 +
  11 +use App\Helper\Translate;
  12 +use App\Models\Inquiry\InquiryRelayDetail;
  13 +use App\Models\Inquiry\InquiryRelayDetailLog;
  14 +use Illuminate\Console\Command;
  15 +use Illuminate\Support\Arr;
  16 +use Illuminate\Support\Facades\Http;
  17 +use Illuminate\Support\Str;
  18 +
  19 +/**
  20 + * Class RelayInquiry
  21 + * @package App\Console\Commands\Inquiry
  22 + */
  23 +class RelayInquiryForward extends Command
  24 +{
  25 + /**
  26 + * The name and signature of the console command.
  27 + *
  28 + * @var string
  29 + */
  30 + protected $signature = 'relay_inquiry_forward';
  31 +
  32 + /**
  33 + * The console command description.
  34 + *
  35 + * @var string
  36 + */
  37 + protected $description = '转发询盘:拆分转发数据';
  38 +
  39 + /**
  40 + * Create a new command instance.
  41 + *
  42 + * @return void
  43 + */
  44 + public function __construct()
  45 + {
  46 + parent::__construct();
  47 + }
  48 +
  49 + /**
  50 + * 模拟访问来源占比
  51 + * @var array
  52 + */
  53 + protected $lyzb = [
  54 + 'https://www.google.com/' => 630,
  55 + 'http://www.google.com/' => 30,
  56 + 'http://www.bing.com/' => 20,
  57 + 'https://www.bing.com/' => 5,
  58 + 'https://www.youtube.com/' => 5,
  59 + 'https://search.yahoo.com/' => 5,
  60 + 'https://www.facebook.com/' => 5,
  61 + ];
  62 +
  63 + /**
  64 + * 俄语站 模拟访问来源占比
  65 + * @var array
  66 + */
  67 + protected $eylyzb = [
  68 + 'https://www.yandex.com/' => 630,
  69 + 'https://www.google.com/' => 30,
  70 + 'http://www.google.com/' => 30,
  71 + 'http://www.bing.com/' => 20,
  72 + 'https://www.bing.com/' => 5,
  73 + 'https://www.youtube.com/' => 5,
  74 + 'https://search.yahoo.com/' => 5,
  75 + 'https://www.facebook.com/' => 5,
  76 + ];
  77 +
  78 + /**
  79 + * PC端访问头信息
  80 + * @var array
  81 + */
  82 + protected $pc_ua = [
  83 + 0 => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_0) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11',
  84 + 1 => 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
  85 + 2 => 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1'
  86 + ];
  87 +
  88 + /**
  89 + * 移动端访问头信息
  90 + * @var array
  91 + */
  92 + protected $mobile_ua = [
  93 + 0 => 'Mozilla/5.0 (Linux; Android 4.2.1; en-us; Nexus 5 Build/JOP40D) AppleWebKit/535.19 (KHTML, like Gecko; googleweblight) Chrome/38.0.1025.166 Mobile Safari/535.19',
  94 + ];
  95 +
  96 + /**
  97 + * google域名后缀
  98 + * @var string[]
  99 + */
  100 + protected $suffix = [
  101 + 'co.jp' => '日本',
  102 + 'com.tr' => '土耳其',
  103 + 'nl' => '荷兰',
  104 + 'ru' => '俄罗斯',
  105 + 'fr' => '法国',
  106 + 'co.kr' => '韩国',
  107 + 'fi' => '芬兰',
  108 + 'be' => '比利时',
  109 + 'lt' => '立陶宛',
  110 + 'es' => '西班牙',
  111 + 'it' => '意大利',
  112 + 'com.au' => '澳大利亚',
  113 + 'no' => '挪威',
  114 + 'al' => '阿尔巴尼亚',
  115 + 'pt' => '葡萄牙',
  116 + 'lv' => '拉脱维亚',
  117 + 'hu' => '匈牙利',
  118 + 'cz' => '捷克',
  119 + 'de' => '德国',
  120 + 'ca' => '加拿大',
  121 + 'co.in' => '印度',
  122 + 'co.uk' => '英国',
  123 + 'com.vn' => '越南',
  124 + 'com.br' => '巴西',
  125 + 'co.il' => '以色列',
  126 + 'pl' => '波兰',
  127 + 'com.eg' => '埃及',
  128 + 'co.th' => '泰国',
  129 + 'sk' => '斯洛伐克',
  130 + 'ro' => '罗马尼亚',
  131 + 'com.mx' => '墨西哥',
  132 + 'com.my' => '马来西亚',
  133 + 'com.pk' => '巴基斯坦',
  134 + 'co.nz' => '新西兰',
  135 + 'co.za' => '南非',
  136 + 'com.ar' => '阿根廷',
  137 + 'com.kw' => '科威特',
  138 + 'com.sg' => '新加坡',
  139 + 'com.co' => '哥伦比亚',
  140 + 'co.id' => '印度尼西亚',
  141 + 'gr' => '希腊',
  142 + 'bg' => '保加利亚',
  143 + 'mn' => '蒙古',
  144 + 'dk' => '丹麦',
  145 + 'com.sa' => '沙特阿拉伯',
  146 + 'com.pe' => '秘鲁',
  147 + 'com.ph' => '菲律宾',
  148 + 'com.ua' => '乌克兰',
  149 + 'ge' => '格鲁吉亚',
  150 + 'ae' => '阿拉伯联合酋长国',
  151 + 'tn' => '突尼斯',
  152 + ];
  153 +
  154 + protected $otherzb = [700, 300]; //模拟访问来源占比 (非美国) google.com|google.其他后缀
  155 +
  156 +
  157 + public function handle()
  158 + {
  159 + while (true) {
  160 + $this->startInquiryDetail();
  161 + }
  162 + }
  163 +
  164 +
  165 + public function startInquiryDetail()
  166 + {
  167 + $inquiry_detail = InquiryRelayDetail::where('status', InquiryRelayDetail::STATUS_INIT)->orderBy('start_at', 'asc')->orderBy('id', 'asc')->first();
  168 + if (!$inquiry_detail) {
  169 + //所有任务执行完成
  170 + sleep(60);
  171 + return true;
  172 + }
  173 +
  174 + try {
  175 + $this->output('询盘详情ID:' . $inquiry_detail['id'] . ',开始拆分转发数据');
  176 +
  177 + $inquiry_detail->status = InquiryRelayDetail::STATUS_PEND;//拆分中
  178 + $inquiry_detail->save();
  179 +
  180 + //先补全询盘详情数据
  181 + $urls = $this->completeDetail($inquiry_detail);
  182 +
  183 + //再拆分转发数据
  184 + $this->relayDetail($inquiry_detail['id'], $urls, $inquiry_detail['start_at']);
  185 +
  186 + $inquiry_detail->status = InquiryRelayDetail::STATUS_SUCCESS;
  187 + $inquiry_detail->save();
  188 +
  189 + $this->output('询盘详情ID:' . $inquiry_detail['id'] . ',拆分转发数据结束');
  190 + } catch (\Exception $e) {
  191 + $inquiry_detail->status = InquiryRelayDetail::STATUS_FAIL;
  192 + $inquiry_detail->remark = mb_substr($e->getMessage(), 0, 200);;
  193 + $inquiry_detail->save();
  194 + $this->output('询盘详情ID:' . $inquiry_detail['id'] . ',拆分转发数据失败,原因:' . $e->getMessage());
  195 + }
  196 +
  197 + return true;
  198 + }
  199 +
  200 + /**
  201 + * 补全询盘详情数据
  202 + * @param $inquiry_detail
  203 + * @return array
  204 + * @author Akun
  205 + * @date 2025/02/25 17:19
  206 + */
  207 + public function completeDetail($inquiry_detail)
  208 + {
  209 + //urls
  210 + $urls = $this->getUrls($inquiry_detail['is_v6'], $inquiry_detail['website'], $inquiry_detail['email']);
  211 +
  212 + //lang
  213 + if (is_numeric($inquiry_detail['message'])) { //数字会被识别为中文
  214 + $lang = 'en';
  215 + } else {
  216 + $translateSl = Translate::translateSl($inquiry_detail['message']);
  217 + $lang = $translateSl['texts']['sl'] ?? 'en';
  218 + }
  219 +
  220 + // 客户端 头信息 来源
  221 + $device_port = $inquiry_detail['email'] ? '1' : '2'; //1 pc 2移动端
  222 + $user_agent = $inquiry_detail['email'] ? Arr::random($this->pc_ua) : Arr::random($this->mobile_ua);
  223 + $referrer = $this->getReferer($inquiry_detail['country'], $lang);
  224 +
  225 + $inquiry_detail->device_port = $device_port;
  226 + $inquiry_detail->user_agent = $user_agent;
  227 + $inquiry_detail->referrer = $referrer;
  228 + $inquiry_detail->urls = json_encode($urls);
  229 + $inquiry_detail->num = count($urls) + 1;
  230 + $inquiry_detail->save();
  231 +
  232 + return $urls;
  233 + }
  234 +
  235 + /**
  236 + * 创建转发详情
  237 + * @param $task_id
  238 + * @param $urls
  239 + * @param $start_at
  240 + * @author Akun
  241 + * @date 2025/02/25 15:41
  242 + */
  243 + public function relayDetail($task_id, $urls, $start_at)
  244 + {
  245 + $pre = 0;
  246 + $seconds = rand(300, 7200); // 开始时间 从5分钟-2小时后开始
  247 + foreach ($urls as $k => $v) {
  248 + $pre++;
  249 + $seconds += rand(5, 60);
  250 + InquiryRelayDetailLog::createInquiryLog($task_id, InquiryRelayDetailLog::TYPE_VISIT, $pre, $v, date('Y-m-d H:i:s', strtotime($start_at) + $seconds));
  251 + // 最后一次访问询盘 加上询盘
  252 + if ($k + 1 >= count($urls)) {
  253 + $seconds += rand(30, 120);
  254 + $pre++;
  255 + InquiryRelayDetailLog::createInquiryLog($task_id, InquiryRelayDetailLog::TYPE_INQUIRY, $pre, $v, date('Y-m-d H:i:s', strtotime($start_at) + $seconds));
  256 + }
  257 + }
  258 + }
  259 +
  260 + /**
  261 + * 获取访问及询盘url
  262 + * @param $is_v6
  263 + * @param $domain
  264 + * @param $email
  265 + * @return array
  266 + * @author Akun
  267 + * @date 2025/02/25 15:45
  268 + */
  269 + public function getUrls($is_v6, $domain, $email)
  270 + {
  271 + // v6:有邮箱推送主站,没有邮箱推送AMP站;v5:仅推送有邮箱到主站
  272 + if ($is_v6) {
  273 + // 获取访问明细和着陆页
  274 + $product_url = $this->getLinksFromSitemap($domain . 'product_sitemap.xml');
  275 + $product_cate_url = $this->getLinksFromSitemap($domain . 'product_category_sitemap.xml');
  276 + $keywords_url = $this->getLinksFromSitemap($domain . 'product_keywords_sitemap.xml');
  277 + $page_url = $this->getLinksFromSitemap($domain . 'page_sitemap.xml');
  278 + } else {
  279 + if ($email) {
  280 + //通过sitemap拿访问页面
  281 + $product_url = $this->getLinksFromSitemap($domain . 'sitemap_post.xml');
  282 + $product_cate_url = $this->getLinksFromSitemap($domain . 'sitemap_category.xml');
  283 + $keywords_url = $this->getLinksFromSitemap($domain . 'sitemap_post_tag.xml');
  284 + $page_url = $this->getLinksFromSitemap($domain . 'sitemap_page.xml');
  285 + } else {
  286 + //m站先就往contact-us着陆
  287 + $product_url = $product_cate_url = $keywords_url = [];
  288 + $page_url = [$domain . 'contact-us/'];
  289 + }
  290 + }
  291 +
  292 + // 所有可用url
  293 + $urls = $inquiry_urls = [];
  294 + //入口url 首页30%,单页10%,聚合页60%
  295 + $type = getRandByRatio([30, 10, 60]);
  296 + $inlet = $domain;
  297 + $type == 1 && $inlet = $page_url ? Arr::random($page_url) : $domain;
  298 + $type == 2 && $inlet = $keywords_url ? Arr::random($keywords_url) : $domain;
  299 + $urls[] = $inquiry_urls[] = $inlet;
  300 + $all_urls = array_merge($urls, $product_url, $product_cate_url, $keywords_url, $page_url);
  301 + $inquiry_urls = array_merge($urls, $product_cate_url, $keywords_url, $page_url);
  302 +
  303 + // 随机访问1-6个页面
  304 + $deep = rand(1, 6);
  305 +
  306 + if(count($all_urls) > 1){
  307 + $visit_urls = Arr::random($all_urls, $deep > count($all_urls) ? count($all_urls) : $deep);
  308 + $urls = array_merge($urls, $visit_urls);
  309 + }
  310 +
  311 + // 推送着落页只能是 首页、产品分类、单页面、聚合页
  312 + if (!in_array(end($urls), $inquiry_urls)) {
  313 + $urls[] = Arr::random($inquiry_urls);
  314 + }
  315 +
  316 + return $urls;
  317 + }
  318 +
  319 + /**
  320 + * 获取头信息
  321 + * @param $ip_area
  322 + * @param $lang
  323 + * @return int|string
  324 + */
  325 + public function getReferer($ip_area, $lang)
  326 + {
  327 + if ($lang == 'ru') {
  328 + return $this->get_rand($this->eylyzb);
  329 + }
  330 + if ($ip_area == '美国') {
  331 + $referer = $this->get_rand($this->lyzb);
  332 + } else {
  333 + $referer = 'https://www.google.com/';
  334 + $suffix = array_search($ip_area, $this->suffix);
  335 + if ($suffix) {
  336 + $res_qtzb = $this->get_rand($this->otherzb);
  337 + if ($res_qtzb == 1) {
  338 + $referer = 'https://www.google.' . $suffix . '/';
  339 + }
  340 + }
  341 + }
  342 + return $referer;
  343 + }
  344 +
  345 + /**
  346 + * 概率算法
  347 + * @param $proArr
  348 + * @return int|string
  349 + */
  350 + protected function get_rand($proArr)
  351 + {
  352 + $result = '';
  353 + $proSum = array_sum($proArr);
  354 + foreach ($proArr as $key => $proCur) {
  355 + $randNum = mt_rand(1, $proSum);
  356 + if ($randNum <= $proCur) {
  357 + $result = $key;
  358 + break;
  359 + } else {
  360 + $proSum -= $proCur;
  361 + }
  362 + }
  363 + unset ($proArr);
  364 + return $result;
  365 + }
  366 +
  367 + /**
  368 + * 获取sitemap内容
  369 + * @param $sitemapUrl
  370 + * @return array|mixed
  371 + */
  372 + function getLinksFromSitemap($sitemapUrl)
  373 + {
  374 + try {
  375 + //忽略cert证书 先下载到临时文件
  376 + $result = Http::withoutVerifying()->get($sitemapUrl)->body();
  377 + $tempFilePath = tempnam(sys_get_temp_dir(), 'remote_file_');
  378 + file_put_contents($tempFilePath, $result);
  379 + $xml = simplexml_load_file($tempFilePath);
  380 + $links = [];
  381 + foreach ($xml->url as $url) {
  382 + $loc = (string)$url->loc;
  383 + if (!Str::contains($loc, ['404', 'thanks', 'test'])) {
  384 + $links[] = $loc;
  385 + }
  386 + }
  387 + //随机取20个
  388 + $total = count($links);
  389 + return Arr::random($links, $total > 20 ? 20 : $total);
  390 + } catch (\Exception $e) {
  391 + echo date('Y-m-d H:i:s') . 'sitemap获取失败:' . $e->getMessage() . PHP_EOL;
  392 + return $links ?? [];
  393 + }
  394 + }
  395 +
  396 + public function output($message)
  397 + {
  398 + echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
  399 + }
  400 +}