微信公众号粉丝查看工具

微信公众号粉丝查看工具,可查看用户关注时间和可导出每页用户数据

目前为 2021-06-19 提交的版本。查看 最新版本

// ==UserScript==
// @name         微信公众号粉丝查看工具
// @namespace    https://mp.weixin.qq.com/cgi-bin/user_tag?action=get_all_data
// @version      0.1.4
// @description  微信公众号粉丝查看工具,可查看用户关注时间和可导出每页用户数据
// @author       Wilson
// @match        https://mp.weixin.qq.com/cgi-bin/user_tag?action=get_all_data*
// @icon         https://img.icons8.com/fluent/48/000000/user-male-circle.png
// @require      https://cdn.jsdelivr.net/npm/[email protected]/jquery.min.js
// @run-at       document-start
// @grant        GM_xmlhttpRequest
// @grant        unsafeWindow
// ==/UserScript==

(function() {
    'use strict';

    //用户数据,记录每次变更的数据
    unsafeWindow.userData = [];
    unsafeWindow.allUserData = [];

    //添加关注信息
    function addFllowInfo(userList) {
        for (let i in userList) {
            //添加关注时间
            let user = userList[i];
            user.user_openid = user.user_openid || user.id;
            user.user_create_time = user.user_create_time || user.create_time;
            let localDate = new Date(user.user_create_time * 1000).toLocaleString();
            //console.log(user.user_create_time, user.user_openid);
            let userName = document.querySelector(".user_info a[data-fakeid=" + user.user_openid + "]");
            //console.log(userName, user.user_openid);
            if (userName) userName.innerHTML += '&nbsp;&nbsp;&nbsp;&nbsp;<span style="color:#9a9a9a;">(' + localDate + ')</span>';
        }

         //导出按钮
         $(".tool_area .pagination").append('<span><a href="javascript:;" onclick="wx_user_export()" style="margin-top:4px;margin-left:15px;display:inline-block;">导出本页</a></span>');
         let btnstyle = 'background-color: #fff;background-image: linear-gradient(to bottom,#fff 0,#fff 100%);border-color: #e7e7eb;color: #353535;height: 30px; line-height: 30px;padding-left: 10px; padding-right: 10px;width: auto;';
         $(".tool_area .pagination").append('<span style="margin-left:20px;">导出前<input id="wx_export_num" type="text" value="'+(unsafeWindow.exportNum||'')+'" style="width:40px;border:1px solid #e7e7eb;height:20px;text-align:center;">页<a id="wx_export_all" href="javascript:;" onclick="wx_user_export_all()" class="btn" style="margin-left:6px;display:inline-block;'+btnstyle+'">导出</a></span>');
    }

    //错误提示
    function errorTips(str, delay) {
        $(".page_tips .inner").html(str);
        $(".page_tips").show();
        setTimeout(function(){
            $(".page_tips").hide();
            $(".page_tips .inner").html("将浏览器更新为QQ浏览器或Chrome浏览器,以获得更好的体验");
        }, delay||3000);
    }

    //监听分页用户(ajax)
    //var lastUserUrl = "";
    (function(open) {
        XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {

            this.addEventListener("readystatechange", function() {

                //console.log(this.readyState, this.status, this);

                if (this.readyState==4 && this.status==200 && url.indexOf("ction=get_user_list") !== -1) {
                    let json = JSON.parse(this.response);
                    //console.log(this.readyState, this.status, json);
                    let userList = json.user_list.user_info_list || [];
                    setTimeout(function(){
                        addFllowInfo(userList);
                    }, 400);
                    unsafeWindow.userData = userList;
                    unsafeWindow.wx_user_export_page++;
                    if(unsafeWindow.isExporting) {
                         for(let j in userList) {
                             if(userList[j]) {
                                 unsafeWindow.allUserData.push(userList[j]);
                             }
                         }
                    }
                }

                /*
                let userUrl = document.location.origin + url;
                if (lastUserUrl != userUrl && url.indexOf("ction=get_user_list") !== -1) {
                    console.log(userUrl);

                    GM_xmlhttpRequest({
                        method: "get",
                        url: userUrl,
                        onload: function(res){
                            if(res.status === 200){
                                console.log('sucess')
                                let json = JSON.parse(res.response);
                                let userList = json.user_list.user_info_list || [];
                                addFllowInfo(userList);
                                unsafeWindow.userData = userList;
                                unsafeWindow.wx_user_export_page++;
                            }else{
                                console.log('error')
                                console.log(res)
                            }
                        },
                        onerror : function(err){
                            console.log('error')
                            console.log(err)
                        }
                    });

                    //$.getJSON(userUrl, function(data){
                    //console.log(data);
                    //$.each(data.items, function(i,item){
                    // });
                    //});
                    lastUserUrl = userUrl;
                }
                */

            }, false);

            open.call(this, method, url, async, user, pass);
        };
    })(XMLHttpRequest.prototype.open);

    //全部导出
    unsafeWindow.isExporting = false;
    unsafeWindow.exportNum = '';
    unsafeWindow.isStop = 0;
    unsafeWindow.wx_user_export_all = function() {
        if(unsafeWindow.isExporting) return false;
        unsafeWindow.isExporting = true;
        let total = parseInt($(".page_num label:last").text()-0);
        let currpage = parseInt($(".page_num label:first").text()-0);
        if(currpage > 1){
            errorTips("请先跳转到第1页");
            unsafeWindow.isExporting = false;
            return false;
        }
        unsafeWindow.allUserData = wx.cgiData.user_list || [];
        let count = unsafeWindow.allUserData.length;
        let begin_openid = unsafeWindow.allUserData[count-1].id;
        let begin_create_time = unsafeWindow.allUserData[count-1].create_time;
        unsafeWindow.exportNum = parseInt($("#wx_export_num").val()-0);
        if(unsafeWindow.exportNum <= 0){
            errorTips("请填写页数");
            unsafeWindow.isExporting = false;
            return false;
        }

        $(".tool_area").append('<div id="wx_export_tips" style="margin-top:10px;"></div>');

        let sleep = function (ms) {
            return new Promise(resolve => setTimeout(resolve, ms));
        }

        let doGetUsers = async function() {
            for(let i = 2;i<=total;i++){
                //停止
                if(unsafeWindow.isStop == 1) {
                    unsafeWindow.isStop = 0;
                    break;
                }
                //超过页数
                if(i > unsafeWindow.exportNum || i > total) break;

                //console.log('page ' + i, 1111, unsafeWindow.isExporting);
                $("#wx_export_tips").html("正在导出第"+i+"页...&nbsp;&nbsp;&nbsp;&nbsp;<a href='javascript:;' onclick='isStop = 1;'>停止</a>");
                document.querySelector("a.page_next").click();

                /*
                let userUrl = "https://mp.weixin.qq.com/cgi-bin/user_tag?action=get_user_list&groupid=-2&begin_openid="+begin_openid+"&begin_create_time="+begin_create_time+"&limit=20&offset=20&backfoward=1&token=" + wx.data.t + "&lang=zh_CN&f=json&ajax=1&random="+Math.random();
                console.log(2222, userUrl);
                GM_xmlhttpRequest({
                    method: "get",
                    url: userUrl,
                    onload: function(res){
                        if(res.status === 200){
                            console.log('sucess')
                            console.log(333, res);
                            let json = JSON.parse(res.response);
                            let userList = json.user_list.user_info_list || [];
                            console.log(4444, userList);
                            for(let j in userList) {
                                if(userList[j]) {
                                    unsafeWindow.allUserData.push(userList[j]);
                                    begin_openid = userList[j].user_openid;
                                    begin_create_time = userList[j].user_create_time;
                                }
                            }
                        }else{
                            console.log('error')
                            console.log(res)
                        }
                    },
                    onerror : function(err){
                        console.log('error')
                        console.log(err)
                    }
                });
                */
                await sleep(2000);
            }
            wx_user_export(unsafeWindow.allUserData, "微信公众号粉丝前"+unsafeWindow.exportNum+"页");
            $("#wx_export_tips").html("");
            unsafeWindow.isExporting = false;
        }
        doGetUsers();
    }

    //导出用户数据
    unsafeWindow.wx_user_export_page = 1;
    unsafeWindow.wx_user_export = function(data, name) {
        //console.log(data,6666);
        let jsonData = data || unsafeWindow.userData;
        //列标题,逗号隔开,每一个逗号就是隔开一个单元格
        let str = `昵称,关注时间,openid,头像图片\n`;
        for (let i in jsonData) {
            let user = jsonData[i];
            user.user_openid = user.user_openid || user.id;
            if (!user.user_openid) continue;
            user.user_create_time = user.user_create_time || user.create_time;
            let localDate = new Date(user.user_create_time * 1000).toLocaleString();
            user.user_name = user.user_name || user.nick_name;
            user.user_head_img = user.user_head_img || document.querySelector(".user_info img[data-id=" + user.user_openid + "]").src;
            str += `${user.user_name},${localDate},${user.user_openid},${user.user_head_img}\n`;
        }
        //encodeURIComponent解决中文乱码
        let uri = 'data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str);
        //通过创建a标签实现
        var link = document.createElement("a");
        link.href = uri;
        //对下载的文件命名
        link.download = (name || "微信公众号粉丝第" + unsafeWindow.wx_user_export_page + "页") + ".csv";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
    }

    //第一页用户数据(从js变量获取)
    window.addEventListener("load", function() {
        if (wx && wx.cgiData && wx.cgiData.user_list) {
            let userList = wx.cgiData.user_list || [];
            addFllowInfo(userList);
            unsafeWindow.userData = userList;

            //首页获取图片地址
            setTimeout(function(){
                for (let i in wx.cgiData.user_list) {
                    let item = wx.cgiData.user_list[i];
                    if (!item.user_head_img) {
                        let imgsrc = document.querySelector(".user_info img[data-id=" + item.id + "]");
                        if(imgsrc) {
                            item.user_head_img = imgsrc.src;
                        } else {
                            item.user_head_img = '';
                        }
                    }
                    wx.cgiData.user_list[i] = item;
                }

            }, 500);
        }
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址