1. 程式人生 > >PHP 結合前端 ajax 爬取網站信息後, 向指定用戶發送指定短信;

PHP 結合前端 ajax 爬取網站信息後, 向指定用戶發送指定短信;

icloud identity coo 請求頭 array -type aid 前端 之前


<?php
/**
 * Description
 * @authors Your Name ([email protected])
 * # 根據時時彩的最新一期的號碼, 判斷如果為首尾同號則發送短信
 *  - phpQuery 分析網頁, 獲得網頁數據, 獲得html數據
 *  - curl_init 模擬真實瀏覽器訪問, 配合 PHPquery
 *  - 根據手機號, 結合前端 get與post 請求發送短信通知
 *  - 使用的 php 的正則, 替換字符串
 *  - 使用 sleep 與 while 反復執行代碼
 *  - 反復執行代碼的同時, 還可以在瀏覽器輸出
 * # 只有刷新 wamp 才能終止進程`
 * # 實際在雲服務中會報錯: FastCGI 進程超過了配置的活動超時時限的解決方法
 *  - 無解
 *  - 所以只能在本機使用wamp開啟
 * @date    2018-07-26 17:13:39
 * @version 1.0.0
 */

header("Content-Type: text/html;charset=utf-8"); 
require('phpQuery/phpQuery.php');
// $eg1=phpQuery::newDocumentFile("http://www.whu.edu.cn/tzgg.htm");
// $eg2=phpQuery::newDocumentFile("https://www.baidu.com/");
// $eg3=phpQuery::newDocumentFile("http://caipiao.163.com/award/cqssc/");
// echo pq("title",$eg1->getDocumentID())->html()."<br>";//$eg1與$eg1->getDocumentID()效果等同
// echo pq("title")->html()."<br>";//就近匹配 $eg2
// phpQuery::selectDocument($eg1); //默認會使用選定的文檔
// $mes=pq("ul")->html();//獲取所有的ul標簽中的html內容
// $mes=pq("ul,li")->html();//獲取所有的ul以及li標簽中的html內容
// $t=pq("ul[class='article']")->html();//獲取ul class="article"的html內容

/***
 * 根據 手機號, 第幾期, 當期號碼 發送短信通知
 */
function fnSendMessageNotifications($mobile, $lotteryNumber1, $lotteryNumber2)
{
  echo '<br>****[' . $mobile . ']****<br>' ;
  echo '<br>****[' . $lotteryNumber1 . ']****<br>' ;
  echo '<br>****[' . $lotteryNumber2 . ']****<br>' ;
  $host = "http://cowsms.market.alicloudapi.com";
  $path = "/intf/smsapi";
  $method = "GET";
  $appcode = "你的appcode";
  $headers = array();
  array_push($headers, "Authorization:APPCODE " . $appcode);
  $querys = "mobile=" . $mobile . "&paras=" . $lotteryNumber1 . "%2C" . $lotteryNumber2 . "&sign=%E6%B6%88%E6%81%AF%E9%80%9A&tpid=155";
  echo '<br>****[' . $querys . ']****<br>' ;
  $bodys = "";
  $url = $host . $path . "?" . $querys;

  $curl = curl_init();
  curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
  curl_setopt($curl, CURLOPT_URL, $url);
  curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($curl, CURLOPT_FAILONERROR, false);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_HEADER, true);
  if (1 == strpos("$".$host, "https://"))
  {
      curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
      curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
  }
  var_dump(curl_exec($curl));
}


/**
 * 添加 USERAGENT , 模擬真實瀏覽器訪問
 * */ 
function get_fcontent($url,  $timeout = 5 ) {
  $url = str_replace( "&", "&", urldecode(trim($url)) );
  $cookie = tempnam ("/tmp", "CURLCOOKIE");
  $ch = curl_init();
  curl_setopt( $ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; rv:1.7.3) Gecko/20041001 Firefox/0.10.1" );
  curl_setopt( $ch, CURLOPT_URL, $url);//需要獲取的URL地址,也可以在 curl_init()函數中設置。
  curl_setopt( $ch, CURLOPT_COOKIEJAR, $cookie );//連接結束後保存cookie信息的文件。
  curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );//啟用時會將服務器服務器返回的"Location: "放在header中遞歸的返回給服務器,使用CURLOPT_MAXREDIRS可以限定遞歸返回的數量。
  curl_setopt( $ch, CURLOPT_ENCODING, "" );//HTTP請求頭中"Accept-Encoding: "的值。支持的編碼有"identity","deflate"和"gzip"。如果為空字符串"",請求頭會發送所有支持的編碼類型。在cURL 7.10中被加入。
  curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );//將 curl_exec()獲取的信息以文件流的形式返回,而不是直接輸出。
  curl_setopt( $ch, CURLOPT_AUTOREFERER, true );//當根據Location:重定向時,自動設置header中的Referer:信息。
  //禁用後cURL將終止從服務端進行驗證。使用CURLOPT_CAINFO選項設置證書使用CURLOPT_CAPATH選項設置證書目錄 如果CURLOPT_SSL_VERIFYPEER(默認值為2)被啟用,CURLOPT_SSL_VERIFYHOST需要被設置成TRUE否則設置為FALSE。自cURL 7.10開始默認為TRUE。從cURL 7.10開始默認綁定安裝。
  curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );   //  # required for https urls, 在發起連接前等待的時間,如果設置為0,則無限等待。
  curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, $timeout );
  curl_setopt( $ch, CURLOPT_TIMEOUT, $timeout ); // 設置cURL允許執行的最長秒數。    
  curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 ); //指定最多的HTTP重定向的數量,這個選項是和CURLOPT_FOLLOWLOCATION一起使用的。
  $content = curl_exec( $ch );
  curl_close ( $ch );
  return $content;
}



// set_time_limit(0); // Maximum execution time , 設置成0的話,就是永不過期。
$lastQi = '';  // foreach保存的最後一個 期號
$lastNumber = ''; // foreach保存的最後一個 號碼
$nTheLastTraversalPeriod = ''; // 緩存上一個foreach的首尾相同的期號, 用以比對是否為最新一期, 也用來當做最後一個符合條件的期號
$nTheLastTraversalNumber = '';
$sessionStorage_cacheQi = ''; // 緩存上一個發送了短信的期號

/**
 * 獲得最新一期期號, 獲得最新一期號碼
 * */
function fnGetTheLatestPhase(){
  //詳細每個curlopt意思.轉http://www.jb51.net/article/39331.htm
  global $lastQi;
  global $lastNumber;
  global $nTheLastTraversalPeriod;
  global $nTheLastTraversalNumber;
  global $sessionStorage_cacheQi;
  $url = 'http://caipiao.163.com/award/cqssc/';        
  $content = get_fcontent($url);
  phpQuery::newDocumentHTML($content);
  
  // $main = pq('title')->html();
  // $table = pq('.award-winNum')->html();
  $table_tr  = pq('tr');
  $nCurrentTerm = '';

  foreach( pq(".award-winNum") as $table_tr ) {
    $nCurrentTerm = pq($table_tr) -> prev()-> html(); // 當前的期號
    $nCurrentNumber = pq($table_tr) -> html();// 當前號碼
    if($nCurrentNumber[0] === $nCurrentNumber[strlen($nCurrentNumber)-1] && intval($nTheLastTraversalPeriod)<intval($nCurrentTerm)){ // 假設當前號碼的首尾相同, 且上一個遍歷的首尾相同的期號小於當前期號(是foreach最後一個遍歷的最大的期號)
      $nTheLastTraversalPeriod = $nCurrentTerm;
      $nTheLastTraversalNumber = $nCurrentNumber;
      echo '<br>****[' . $nTheLastTraversalPeriod . ']****<br>' ;
    }
    if($nCurrentTerm === '001' && !is_numeric(preg_replace('/ /', '', $nCurrentNumber))){
      // 假設重新開始, 每天新一期, 舊的還在緩存, 如何辦?
      // 假設當前的期號為001, 表示的時時彩從頭開始, 此時需要:
      // - 刪除緩存的上一個發送短信的期號
      // - 刪除緩存的上一個首尾相同的期號
      $nTheLastTraversalPeriod = '';
      $sessionStorage_cacheQi = '';
    }

    // // echo pq($table_tr); 
    // $text = pq($table_tr) -> html();// 號碼
    // $_lastQi = pq($table_tr) -> prev()-> html(); // 當前元素的上一個元素
    // echo '<br>****[' . $nTheLastTraversalPeriod . ']****<br>' ;
    // if($text[0] === $text[strlen($text)-1] && intval($sessionStorage_cacheQi||'')<intval($_lastQi) && intval($nTheLastTraversalPeriod)<intval($_lastQi) ){
    // if($text[0] === $text[strlen($text)-1] && intval($nTheLastTraversalPeriod)<intval($_lastQi) ){
    
    echo '<br>';
  }
  echo '<hr>';

  if($nTheLastTraversalPeriod !== $sessionStorage_cacheQi){ 
    // 假設沒有值得發送的期號, 假設當前發送的期號與之前發送的期號不同(不能相同), 則不執行相關代碼(發送短信)
    $sessionStorage_cacheQi = $nTheLastTraversalPeriod;
    $object = (object) [
      'nPeriodNumber' => $nTheLastTraversalPeriod,
      'nNumber' => preg_replace('/ /', '', $nTheLastTraversalNumber),
    ];
    return $object;
  }else{
    $object = (object) [
      'nPeriodNumber' => '',
      'nNumber' => '',
    ];
    return $object;
  }
}
// var_dump(fnGetTheLatestPhase());

// $options = fnGetTheLatestPhase();
// fnSendMessageNotifications('185********', $options->nPeriodNumber, $options->nNumber);
while (1) {
  $options = fnGetTheLatestPhase();
  
  // 兩者必須同時使用來刷新輸出緩沖
  ob_flush(); //將數據從php的buffer中釋放出來
  flush(); //將釋放出來的數據發送給瀏覽器, 要是沒有 flush 和 ob_flush , 瀏覽器就會陷入一種假卡死的狀態
  
  var_dump($options);
  if($options->nPeriodNumber){
    fnSendMessageNotifications('185****', $options->nPeriodNumber, $options->nNumber);
  }
  sleep(5);
}

原文地址:https://segmentfault.com/a/1190000015798666

PHP 結合前端 ajax 爬取網站信息後, 向指定用戶發送指定短信;