eve吧 关注:576,838贴子:27,768,579
  • 22回复贴,共1

一个业余php程序员的编程生活

只看楼主收藏回复

PHP全靠自学,最近因为工作和兴趣做了2个小项目,先说第一个吧,当然是大家喜闻乐见的eve市场分析。下面来慢慢讲。


1楼2021-09-17 09:57回复
    作为一个老屁股,怪刷不动,制造生产也不想搞,于是就每天蹲站挂单维持下生活的样子,一直以来都想做一个自己的eve市场分析工具(实在是消息闭塞,没有相关资源),刚开始是用的表格,一个是WPS不支持网页数据导入,而是哪怕是使用宏,感觉效率也还是低下、麻烦。
    前半个月的时候终于决定做出来,刚开始选择的是JS(调试方便啊),从数据抓取速度来讲还是很快的,但是对于DOM、JS实在不是很熟悉,而且要完成具体任务需要查询2个API,导致任务异常复杂,后来就转向PHP开发了,奋战(划水)了几天。终于初步实现了预想功能,废话不多说,就来上源码分享给大家。


    2楼2021-09-17 10:12
    收起回复
      2026-03-18 05:07:31
      广告
      不感兴趣
      开通SVIP免广告
      先上拉取市场订单的源码:已经专门加了部分注释,不懂请搭楼咨询,勿要重复盖楼,方便统一回复。
      <?php
      $mysqli = new mysqli('127.0.0.1', 'root', '', 'new'); //本地数据库连接
      set_time_limit(0);
      $time = microtime(true);
      echo '<pre>开始时间' . date('Y-m-d H:i:s', time()) . '<br>';
      $data = [];
      $count = 140;//因为网易不返回总页数,实测基本大于总页数,可以了
      for ($i=1; $i <$count ; $i++) { //10000002 吉他所在星域,查询其他地域请自行修改
      $url = 'https://esi.evepc.163.com/latest/markets/10000002/orders/?datasource=serenity&order_type=all&page='.$i;
      $data[]['url'] = $url;//构造esi连接,词链接不需要授权,放心使用
      }
      function getMultiCurlResult($data = [], $timeout = 120)//CURL异步获取数据,提升数据获取效率
      {
      $request = [];
      $requestResource = curl_multi_init();
      foreach ($data as $k => $v) {
      $option = [
      CURLOPT_TIMEOUT => $timeout,//请求超时时间,防止死循环
      CURLOPT_RETURNTRANSFER => true,//获取的信息以文件流的形式返回,而不是直接输出。
      ];
      if (!isset($v['url']) || !$v['url']) return null;
      $option[CURLOPT_URL] = trim($v['url']);
      if (stripos($v['url'], 'https') === 0) $option[CURLOPT_SSL_VERIFYPEER] = false;
      if (isset($v['data'])) {//如果设置了请求参数,则是POST请求
      $option[CURLOPT_POST] = true;
      $option[CURLOPT_POSTFIELDS] = http_build_query($v['data']);
      }
      //启动一个curl会话
      $request[$k] = curl_init();
      //设置请求选项
      curl_setopt_array($request[$k], $option);
      //添加请求句柄
      curl_multi_add_handle($requestResource, $request[$k]);
      }
      $running = null;
      $result = [];
      do {//执行批处理句柄
      //CURLOPT_RETURNTRANSFER如果为0,这里会直接输出获取到的内容.如果为1,后面可以用curl_multi_getcontent获取内容.
      curl_multi_exec($requestResource, $running);
      //阻塞直到cURL批处理连接中有活动连接,不加这个会导致CPU负载超过90%.
      curl_multi_select($requestResource);
      } while ($running > 0);
      foreach ($request as $k => $v) {
      $result[$k] = curl_multi_getcontent($v);
      curl_multi_remove_handle($requestResource, $v);
      }
      curl_multi_close($requestResource);
      return $result;
      }
      $res = getMultiCurlResult($data);
      unset($data);
      //数据计算与写入数据库
      //print_r($res);
      foreach($res as $k => $v)
      {
      $arr=json_decode($v,true);
      //print_r($arr);
      foreach($arr as $key => $value)
      {
      if(@$value['location_id']==60003760)//吉他海4,如获取其他地区请自行更换
      {
      $price=$value['price'];
      if($value['is_buy_order']!=1)
      {
      if(isset($data[$value['type_id']]['卖单最低价']))
      {
      if($data[$value['type_id']]['卖单最低价']>$price)
      {
      $data[$value['type_id']]['卖单最低价']=$price;//卖价卖单最低价
      }
      }else{
      $data[$value['type_id']]['卖单最低价']=$price;
      }
      }
      if($value['is_buy_order']==1)
      {
      if(isset($data[$value['type_id']]['买单最高价']))
      {
      if($data[$value['type_id']]['买单最高价']<$price)
      {
      $data[$value['type_id']]['买单最高价']=$price;//买单买单最高价
      }
      }else{
      $data[$value['type_id']]['买单最高价']=$price;
      }
      }
      }
      }
      }
      $t=time();
      foreach($data as $type_id => $value)
      {
      if(isset($data[$type_id]['卖单最低价']) and isset($data[$type_id]['买单最高价']))
      {
      $data[$type_id]['利率']=round(($data[$type_id]['卖单最低价']-$data[$type_id]['买单最高价'])*100/$data[$type_id]['买单最高价']).'%';
      }else{
      if(!isset($data[$type_id]['卖单最低价']))
      {
      $data[$type_id]['卖单最低价']='';
      }
      if(!isset($data[$type_id]['买单最高价']))
      {
      $data[$type_id]['买单最高价']='';
      }
      $data[$type_id]['利率']='0';
      }
      //写入数据库
      if($data[$type_id]['利率']!='0')
      {
      $lv=$data[$type_id]['利率'];
      $zdj=$data[$type_id]['卖单最低价'];
      $zgj=$data[$type_id]['买单最高价'];
      $sql="UPDATE eve SET 卖单最低价='$zdj',买单最高价='$zgj',利率='$lv',更新时间戳='$t' WHERE typeID='$type_id'";
      //echo $sql.'<br>';
      $query=$mysqli->query($sql);
      }
      }
      $cost = microtime(true) - $time;
      echo "结束时间" . date('Y-m-d H:i:s', time()) . ', 耗时 '. sprintf('%.5f', $cost) . 's, 平均每个耗时:' . sprintf('%.5f', $cost / $count) . 's <br>';
      ?>


      3楼2021-09-17 10:22
      回复
        以上为通过ESI拉取吉他挂单数据,获取最低卖单和最高收单,并计算利率(未计熟虑,使用谨慎,亏本不负责哦)。


        4楼2021-09-17 10:29
        回复
          接下来就是获取每日物品销售量(因为没有找到日均收单、卖单价格数据,如ESI有,请告知),计算市场日均贸易量(最近一个月日均)和贸易额,因为数量量大,物品数量多,要是按照上面的方法一次性拉取网页会卡死,所以采用一次获取一个物品的历史数据,需要注意的预估利润其实为日贸易额,懒得改数据库了,使用者自行注意,下面先贴获取单项物品数据的代码:
          <?php
          //处理单个物品历史成交数据
          $mysqli = new mysqli('127.0.0.1', 'root', '', 'new');
          set_time_limit(0);
          echo '<pre>';
          $type_id=$_GET['type_id'];
          $data=[];
          $url = 'https://esi.evepc.163.com/latest/markets/10000002/history/?datasource=serenity&type_id='.$type_id;
          $data[]['url'] = $url;
          function getMultiCurlResult($data = [], $timeout = 120)
          {
          $request = [];
          $requestResource = curl_multi_init();
          foreach ($data as $k => $v) {
          $option = [
          CURLOPT_TIMEOUT => $timeout,//请求超时时间,防止死循环
          CURLOPT_RETURNTRANSFER => true,//获取的信息以文件流的形式返回,而不是直接输出。
          ];
          if (!isset($v['url']) || !$v['url']) return null;
          $option[CURLOPT_URL] = trim($v['url']);
          if (stripos($v['url'], 'https') === 0) $option[CURLOPT_SSL_VERIFYPEER] = false;
          if (isset($v['data'])) {//如果设置了请求参数,则是POST请求
          $option[CURLOPT_POST] = true;
          $option[CURLOPT_POSTFIELDS] = http_build_query($v['data']);
          }
          //启动一个curl会话
          $request[$k] = curl_init();
          //设置请求选项
          curl_setopt_array($request[$k], $option);
          //添加请求句柄
          curl_multi_add_handle($requestResource, $request[$k]);
          }
          $running = null;
          $result = [];
          do {//执行批处理句柄
          //CURLOPT_RETURNTRANSFER如果为0,这里会直接输出获取到的内容.如果为1,后面可以用curl_multi_getcontent获取内容.
          curl_multi_exec($requestResource, $running);
          //阻塞直到cURL批处理连接中有活动连接,不加这个会导致CPU负载超过90%.
          curl_multi_select($requestResource);
          } while ($running > 0);
          foreach ($request as $k => $v) {
          $result[$k] = curl_multi_getcontent($v);
          curl_multi_remove_handle($requestResource, $v);
          }
          curl_multi_close($requestResource);
          return $result;
          }
          $res = getMultiCurlResult($data);
          unset($data);
          $data=[];
          //print_r($res);
          foreach($res as $k => $v)
          {
          $arr=json_decode($v,true);
          $arr=array_slice($arr,-30);
          //print_r($arr);
          foreach($arr as $key => $value)
          {
          $volume=$value['volume'];
          $average=$value['average'];
          if(!isset($data['highest']))
          {
          $data['近期日均交易量']=$volume;
          $data['日销售额']=$average*$volume;
          }else{
          $data['近期日均交易量']=$data['近期日均交易量']+$volume;
          $data['日销售额']=$data['日销售额']+$average*$volume;
          }
          }
          }
          $data['近期日均售价']=$data['日销售额']/$data['近期日均交易量'];
          $data['近期日均交易量']=round($data['近期日均交易量']/30);
          $t=time();
          $sql="UPDATE eve SET 近期日均交易量='".$data['近期日均交易量']."',近期日均价格='".$data['近期日均售价']."' WHERE typeID=$type_id";
          echo $sql.'<br>';
          $query=$mysqli->query($sql);
          ?>


          5楼2021-09-17 10:35
          回复
            坐等大佬更新


            来自Android客户端6楼2021-09-17 10:45
            收起回复
              楼主代码可以放到gitee上


              IP属地:江苏来自Android客户端7楼2021-09-17 12:14
              收起回复
                来波开源开发吧


                IP属地:湖南来自Android客户端8楼2021-09-17 12:20
                回复
                  2026-03-18 05:01:31
                  广告
                  不感兴趣
                  开通SVIP免广告
                  能直接求成品么,码盲


                  来自iPhone客户端9楼2021-09-17 12:41
                  收起回复
                    某群员帮顶


                    IP属地:浙江10楼2021-09-17 19:30
                    回复