最近需要做一个公众号文章阅读奖励积分的功能,首先就得获取到文章列表,网上查了资料后,感觉微信公众平台图文编辑那的限制会少一点,可以满足需求,现在记录一下
一:首先创建一个登陆表单,包含账户和密码,点击登陆后台请求对应接口获得一个二维码图片,然后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,存在则获取文章列表

6600

被折叠的 条评论
为什么被折叠?



