微信公眾號文章列表抓取


最近需要做一個公眾號文章閱讀獎勵積分的功能,首先就得獲取到文章列表,網上查了資料后,感覺微信公眾平台圖文編輯那的限制會少一點,可以滿足需求,現在記錄一下

一:首先創建一個登陸表單,包含賬戶和密碼,點擊登陸后台請求對應接口獲得一個二維碼圖片,然后js循環刷新顯示二維碼直到掃碼成功(賬號密碼為微信公眾平台的賬號密碼)

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
</head>
<body>
    <input id="name" type="text" placeholder="賬戶">
    <input id="pwd" type="password" placeholder="密碼"> 
    <input onclick="showimg()" type="button" value="登錄">
    <div id="showimg" style="display:none">正在獲取...</div>
<script  src="http://libs.baidu.com/jquery/1.7.2/jquery.min.js"></script>
<script>
    function showimg() {
        $("#showimg").show();
        name = $("#name").val();
        pwd = $("#pwd").val();
        t = setInterval("img()", 3000);
        $.post("./wx.php?method=login", {'name':name, 'pwd':pwd},function(rsg){
            data = jQuery.parseJSON(rsg);
            if(!data.code) {
                window.location.href = "./wx.php?method=getwx";
            }else{
                $("#showimg").hide();
                alert(data.msg);
            }
        })
    }
    function img() {
        num = Math.round(Math.random());
        $("#showimg").html("<img src='./wx/qrcode_tmall.png?"+num+"'>")
    }
</script>
</body>
</html>

二:控制器接收請求處理(Wx.php)

<?php
namespace app;

use app\Wxlogin;

class Wx
{
    //登陸
    function login() {
        $name = $_POST['name'];
        if(!$name)
            return $this->ajax(['code'=>2, 'msg'=>'賬號不能為空']);
        $pwd = $_POST['pwd'];
        if(!$pwd)
            return $this->ajax(['code'=>2, 'msg'=>'密碼不能為空']);
        $arr = array(
          'account'  => $name,
          'password' => $pwd,
          'key'    => "tmall",
        );
        $wx = new Wxlogin();
        $wx->init($arr);
        if(!$wx->getToken()){
            return $this->ajax(['code'=>1, 'msg'=>'登陸失敗'], );
        }
        return $this->ajax(['code'=>0, 'msg'=>'登陸成功']);
    }

    //搜索公眾號(備用,只查看單個公眾號無需使用,fackid固定即可;搜索公眾號查看會用到此方法,然后需要把getwx里的獲取fackid更改一下【session或者參數形式都可以】)
    function getfackid(){
        $search = isset($_GET['search']) ? $_GET['search'] : '內涵段子';
        $wx = new Wxlogin();
        $arr = array(
          'key'    => "tmall",
        );
        //沒有token就去登陸掃碼
        if(!$wx->getToken()){
            header('location:/');
        }
        //開始位置
        $size = 5;
        $nowpage = isset($_GET['page']) ? $_GET['page'] : 1;
        $nowpage = $nowpage<1?1:$nowpage;
        $begin = ($nowpage-1)*$size;
        //初始化並獲取數據
        $wx->init($arr);
        $data = $wx->getfackid($begin, $search);if($data['base_resp']['ret'] != 0) {
            file_put_contents("./wx/token.txt", '');
            switch ($data['base_resp']['ret']) {
                case '200013':
                    echo '請求太頻繁了';
                    break;
                case '200003':
                    echo '無效會話';
                    break;
                default:
                    echo '請求錯誤';
                    break;
            }
            return;
        }else{
            //總頁數
            $psum = ceil($data['app_msg_cnt']/$size);
            $list = $data['app_msg_list'];
        }
        return $this->ajax($list);
    }

    //獲取列表(分頁,頁面條數不足的代表發布者刪除過一些)
    function getwx(){
        $wx = new Wxlogin();
        $arr = array(
          'key'    => "tmall",
        );
        //沒有token就去登陸掃碼
        if(!$wx->getToken()){
            header('location:/');
        }
        //登陸成功刪除二維碼
        if(file_exists('./wx/qrcode_tmall.png')) {
            unlink('./wx/qrcode_tmall.png');
        }
        //開始位置
        $size = 5;
        $nowpage = isset($_GET['page']) ? $_GET['page'] : 1;
        $nowpage = $nowpage<1?1:$nowpage;
        $begin = ($nowpage-1)*$size;
        //初始化並獲取數據
        $wx->init($arr);
        $search = isset($_GET['search']) ? $_GET['search'] : 1;
        $data = $wx->getwx($begin, $search);
        if($data['base_resp']['ret'] != 0) {
            file_put_contents("./wx/token.txt", '');
            switch ($data['base_resp']['ret']) {
                case '200013':
                    echo '請求太頻繁了';
                    break;
                case '200003':
                    echo '無效會話';
                    break;
                default:
                    echo '請求錯誤';
                    break;
            }
            return;
        }else{
            //總頁數
            $psum = ceil($data['app_msg_cnt']/$size);
            $list = $data['app_msg_list'];
        }
        return $this->ajax([$data['app_msg_cnt'], $search, $nowpage, $psum, $list]);
    }

    function ajax($data)
    {
        return json_encode($data, JSON_UNESCAPED_UNICODE);
    }

}

//自動加載
spl_autoload_register(function ($class) {
    $arr = explode('\\', $class);
    if(array_shift($arr) == 'app') {
        include implode('\\', $arr) . '.php';
    }
});

$wx = new Wx();
$method = $_GET['method'];
echo $wx->$method();

 

三:請求微信接口,供Wx.php調用(Wxlogin.php)

<?php
namespace app;

class Wxlogin
{
    //--------------------------------------------------------LOGIN START
    private $_apis = [
        "host" => "https://mp.weixin.qq.com",
        "login" => "https://mp.weixin.qq.com/cgi-bin/bizlogin?action=startlogin",
        "qrcode" => "https://mp.weixin.qq.com/cgi-bin/loginqrcode?action=getqrcode&m=4300",
        "loginqrcode" => "https://mp.weixin.qq.com/cgi-bin/loginqrcode?action=ask&token=&lang=zh_CN&f=json&ajax=1",
        "loginask" => "https://mp.weixin.qq.com/cgi-bin/loginqrcode?action=ask&token=&lang=zh_CN&f=json&ajax=1&random=",
        "loginauth" => "https://mp.weixin.qq.com/cgi-bin/loginauth?action=ask&token=&lang=zh_CN&f=json&ajax=1",
        "bizlogin" => "https://mp.weixin.qq.com/cgi-bin/bizlogin?action=login&lang=zh_CN"
    ];
    public $fakeid = "MzIxMTU3MDA4Ng==";
    private $_redirect_url = "";
    private $_key = "";

    //獲取cookie保存文件,用於訪問接口
    private function _getCookieFile(){
        return "./wx/cookie_{$this->_key}.text";
    }

    //獲取二維碼路徑
    private function _getSavePath(){
        return './wx/'.$this->_qrcodeName();
    }

    //獲取二維碼名稱
    private function _qrcodeName(){
        return "qrcode_{$this->_key}.png";
    }

    //記錄日志
    private function _log($log_content){
        $log_filename = './wx';
        !is_dir($log_filename) && mkdir($log_filename, 0755, true);

        file_put_contents($log_filename.'/wx.log', '['.date("Y-m-d H:i:s").']' .PHP_EOL . $log_content . PHP_EOL."------------------------ --------------------------".PHP_EOL, FILE_APPEND);
    }

    public function getToken(){
        return file_get_contents("./wx/token.txt");
    }
    public function setToken($token){
        file_put_contents("./wx/token.txt", $token);
    }
    public function init($options){
        if(!isset($options["key"])){
            die("Key is Null!");
        }
        $this->_key = $options["key"];
        if($this->getToken()){
            $this->_log("HAS Token !");
            return;
        }else{
            $this->fetch("https://mp.weixin.qq.com/","","text");
            $this->_log("start login!!");
            $this->start_login($options);
        }
    }
    private function start_login($options){
        $_res = $this->_login($options["account"],$options["password"]);
        if($_res["code"]){
            $this->_log($_res["msg"]);
            return;
        }
        //保存二維碼
        $this->_saveQRcode();
        $_ask_api = $this->_apis["loginask"];
        $_input["refer"] = $this->_redirect_url;
        $_index = 1;
        while(true){
            if($_index>20){
                $this->_log("超時");
                break;
            }
            $_res = $this->fetch($_ask_api.$this->getWxRandomNum(),$_input);
            $_status = $_res["status"];
            if($_status==1){
                if($_res["user_category"]==1){
                    $_ask_api = $this->_apis["loginauth"];
                }else{
                    $this->_log("Login success");
                    break;
                }
            }else if($_status==4){
                $this->_log("已經掃碼");
            }else if($_status==2){
                $this->_log("管理員拒絕");
                break;
            }else if($_status==3){
                $this->_log("登錄超時");
                break;
            }else{
                if($_ask_api==$this->_apis["loginask"]){
                    $this->_log("請打開test.jpg,用微信掃碼");
                }else{
                    $this->_log("等待確認");
                }
            }
            sleep(2);
            $_index++;
        }
        $this->_log("開始驗證");
        $_input["post"] = ["lang"=>"zh_CN","f"=>"json","ajax"=>1,"random"=>$this->getWxRandomNum(),"token"=>""];
        $_input["refer"] = $this->_redirect_url;
        $_res = $this->fetch($this->_apis["bizlogin"],$_input);
        $this->_log(print_r($_res,true));
        if($_res["base_resp"]["ret"]!=0){
            $this->_log("error = ".$_res["base_resp"]["err_msg"]);
            return ;
        }
        $redirect_url = $_res["redirect_url"];//跳轉路徑
        if(preg_match('/token=([\d]+)/i', $redirect_url,$match)){//獲取cookie
            $this->setToken($match[1]);
        }
        $this->_log("驗證成功,token: ".$this->getToken());
    }
    //下載二維碼
    private function _saveQRcode(){
        $_input["refer"] = $this->_redirect_url;
        $_res = $this->fetch($this->_apis["qrcode"],$_input,"text");
        $fp = fopen($this->_getSavePath(), "wb+") or die("open fails");
        fwrite($fp,$_res) or die("fwrite fails");
        fclose($fp);
    }

    private function _login($_username,$_password){
        $_input["post"] = array(
            'username' => $_username,
            'pwd' => md5($_password),
            'f' => 'json',
            'imgcode' => ""
        );
        $_input["refer"] = "https://mp.weixin.qq.com";
        $_res = $this->fetch($this->_apis["login"],$_input);
        if($_res["base_resp"]["ret"]!==0){
            return ['code'=>'1', 'msg'=>$_res["base_resp"]["err_msg"]];
        }
        $this->_redirect_url = "https://mp.weixin.qq.com".$_res["redirect_url"];//跳轉路徑
        return ['code'=>'0', 'msg'=>'ok'];
    }

    function getWxRandomNum(){
        return "0.".mt_rand(1000000000000000,9999999999999999);
    }

    function getfackid($begin, $search){
        $url = "https://mp.weixin.qq.com/cgi-bin/searchbiz?action=search_biz&begin=$begin&count=5&query=$search&token=".$this->getToken()."&lang=zh_CN&f=json&ajax=1";
        return $this->fetch($url);
    }

    function getwx($begin, $search){
        $url = "https://mp.weixin.qq.com/cgi-bin/appmsg?action=list_ex&begin=$begin&count=5&fakeid=".$this->fakeid."&type=9&query={$search}&token=".$this->getToken()."&lang=zh_CN&f=json&ajax=1";
        return $this->fetch($url);
    }

    /**
    * @param $url
    * @param null $_input
    * @param string $data_type
    * @return mixed
    * $_input= ["post"=>[],"refer"=>"",cookiefile='']
    */
    function fetch( $url, $_input=null, $data_type='json') {
        $ch = curl_init();
        $useragent = isset($_input['useragent']) ? $_input['useragent'] : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20100101 Firefox/10.0.2';
        curl_setopt( $ch, CURLOPT_URL, $url );
        curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
        curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
        curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
        curl_setopt( $ch, CURLOPT_POST, isset($_input['post']) );
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); //不驗證證書
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); //不驗證證書
        if( isset($_input['post']) ) curl_setopt( $ch, CURLOPT_POSTFIELDS, $_input['post'] );
        if( isset($_input['refer']) ) curl_setopt( $ch, CURLOPT_REFERER, $_input['refer'] );
        curl_setopt( $ch, CURLOPT_USERAGENT, $useragent );
        curl_setopt( $ch, CURLOPT_CONNECTTIMEOUT, ( isset($_input['timeout']) ? $_input['timeout'] : 5 ) );
        curl_setopt( $ch, CURLOPT_COOKIEJAR, ( isset($_input['cookiefile']) ? $_input['cookiefile'] : $this->_getCookieFile() ));
        curl_setopt( $ch, CURLOPT_COOKIEFILE, ( isset($_input['cookiefile']) ? $_input['cookiefile'] : $this->_getCookieFile() ));
        $result = curl_exec( $ch );
        curl_close( $ch );
        if ($data_type == 'json') {
            $result = json_decode($result,true);
        }
        return $result;
    }
}

 注:fakeid是要抓去的公眾號的標識(調用本文的getfackid也可以),也可在公眾平台的圖文編輯里獲取,步驟如下:

1:新建圖文消息

 

2:打開開發者工具,點擊超鏈接,輸入要查詢的公眾號,點擊搜索

3:在開發者工具查看Network一欄中點擊searchbiz...這一欄查看fakeid

補充:

因為我是獲取單個公眾號,所以沒有用getfackid方法,有做公眾號搜索模式的,可以調用上面的getfackid方法獲取公眾號fackid
思路:獲取到公眾號列表后展現給前端,前端點擊選擇提交給后端,后端將對應的fackid存入session,然后獲取文章列表的接口判斷是否存在session,存在則獲取文章列表


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM