持续更新,构建微信公众号批量收款系统
优采云 发布时间: 2020-08-07 06:20自2014年以来,我一直在批量采集微信官方帐户的内容. 最初的目的是建立一个html5垃圾邮件网站. 当时,垃圾站采集到的微信公众号的内容很容易在该公众号中传播. 当时,批量采集特别容易进行,并且采集条目是官方帐户的历史新闻页面. 现在这个入口是一样的,但是采集起来越来越难了. 采集方法也已在许多版本中更新. 后来,在2015年,html5垃圾站没有这样做. 取而代之的是将采集目标定位在本地新闻信息公共帐户上,并将前端显示制作成应用程序. 这样就形成了一个新闻应用程序,它可以自动采集官方帐户的内容. 我曾经担心微信技术升级后的一天,我将无法采集内容,而我的新闻应用程序也会失败. 但是随着微信技术的不断升级,收款方式也有了升级,这使我越来越有信心. 只要存在官方帐户历史记录页面,就可以分批采集内容. 因此,今天我决定整理采集方法并写下来. 我的方法来自许多同事的共享精神,因此我将继续这种精神并分享我的结果.
本文将继续更新,并且您所看到的将保证在您看到时可用.
首先,让我们看一下微信官方帐户历史记录消息页面的链接地址:
http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MjM5MzczNjY2NA==#wechat_webview_type=1&wechat_redirect
==========更新于2017年1月11日=========
现在,根据不同的微信个人帐户,将有两个不同的历史消息页面地址. 以下是另一个历史消息页面的地址. 第一种地址类型的链接将显示302在anyproxy中的跳转:
https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzA3NDk5MjYzNg==&scene=124#wechat_redirect
第一个链接地址的页面样式:
第二个链接地址的页面样式:
根据当前信息,两种页面格式在不同的微信账户中不规则地出现. 一些WeChat帐户始终是第一页格式,而某些始终是第二页格式.
以上链接是指向微信公众号历史新闻页面的真实链接,但是当我们在浏览器中输入此链接时,它将显示: 请从微信客户端访问. 这是因为实际上此链接地址需要几个参数才能正常显示内容. 让我们看一下可以正常显示内容的完整链接:
//第一种链接
http://mp.weixin.qq.com/mp/getmasssendmsg?__biz=MjM5NTM1NjczMw==&uin=NzM4MTk1ODgx&key=a226a081696afed0d9dfa0972fa431e116e5*敏*感*词*572ce52343178ad4e9a2b94aeaad6a*敏*感*词*dd87de3e56f72209a73a32e9cc2052f68aca4884e36cf726e99f2671630c741d8e4c29abe4a049d1a71eeb2be5&devicetype=android-17&version=2605033c&lang=zh_CN&nettype=WIFI&ascene=1&pass_ticket=zbA7PswOPKySRpyEYI5kDCjRiljxcpzdbTuVMauFGemgdp8R1DY1uQY49srehWab&wx_header=1
//第二种
http://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=MzA3NDk5MjYzNg==&scene=124&uin=NzM4MTk1ODgx&key=5134ab1cc362a0324183dbd55a2680d11ccbaa34cdb349ee9be58f5b666092ddb17adf8a88dc788831923f3c6087547d651f04209f72334d511c9e118a3800d7b05a324a38903f79cff940cf749ecd5a&devicetype=android-17&version=2605033c&lang=zh_CN&nettype=WIFI&a8scene=3&pass_ticket=Fo3zjtJcbPfijNHKUIQbV%2BeHsAqhbjJCwzTfV48u%2FCZRRGTmI8oqmHDxxfEL8ke%2B&wx_header=1
在通过微信客户端打开历史消息页面后,使用稍后描述的代理服务器软件获得此地址. 有几个参数:
action =; __ biz =; uin =; key =; devicetype =; version =; lang =; nettype =; scene =; pass_ticket =; wx_header =;
重要参数是: __biz; uin =; key =; pass_ticket =;这四个参数.
__ biz是官方帐户的类似id的参数. 每个官方帐户都有一个微信业务. 目前,官方帐户的业务更改的可能性很小;
其余3个参数与用户的ID和令牌票证有关. 这3个参数的值由微信客户端生成后会自动添加到地址栏中. 因此,我们必须使用微信客户端应用程序来采集官方帐户. 在以前的微信中,这三个参数也可以一次获取,然后在有效期内可以使用多个官方账号. 每次访问正式帐户时,当前版本已经更改了参数值.
我现在使用的方法只需要注意__biz参数.
我的采集系统由以下部分组成:
1. 微信客户端: 可以是安装了微信应用程序的手机,也可以是计算机中的Android模拟器. 经过批处理测试的ios微信客户端的崩溃率高于Android系统. 为了降低成本,我使用了Android模拟器.
2. WeChat个人帐户: 为了采集内容,不仅需要WeChat客户,还需要专用于采集的WeChat个人帐户,因为该WeChat帐户不能做其他事情.
3. 本地代理服务器系统: 当前使用的方法是通过Anyproxy代理服务器将官方帐户历史记录消息页面中的文章列表发送到其自己的服务器. 具体安装方法将在后面详细说明.
4. 文章列表分析和存储系统: 我使用php语言编写它. 下一篇文章将详细介绍如何分析文章列表并建立采集队列以实现内容的批量采集.
步骤
1. 安装模拟器或使用手机安装微信客户端应用程序,申请微信个人帐号并登录. 我不会介绍太多,每个人都会.
二,代理服务器系统的安装
当前,我使用Anyproxy,AnyProxy. 该软件的功能是您可以获取https链接的内容. 2016年初,微信公众号和微信文章开始使用https链接. 而且Anyproxy可以通过修改规则配置将脚本代码插入官方帐户页面. 安装和配置过程将在下面介绍.
1. 安装NodeJS
2. 在命令行或终端上运行npm install -g anyproxy,并且需要将sudo添加到mac系统;
3. 生成RootCA,https需要此证书: 运行命令sudo anyproxy --root(Windows可能不需要sudo);
4. 启动anyproxy以运行命令: sudo anyproxy -i;参数-i表示解析HTTPS;
5. 安装证书,在手机或Android模拟器中安装证书:
6. 设置代理: Android*敏*感*词*的代理服务器地址是wifi链接的网关. 通过dhcp将其设置为静态后,您可以看到网关地址. 阅读后不要忘记将其设置为自动. 电话中的代理服务器地址是运行anyproxy的计算机的ip地址. 代理服务器的默认端口为8001;
现在打开微信,单击任何官方帐户历史记录消息或文章,您可以在终端中看到响应代码滚动. 如果没有出现,请检查手机的代理设置是否正确.
现在打开浏览器地址localhost: 8002以查看anyproxy的Web界面. 单击以从微信打开历史消息页面,然后查看浏览器的Web界面,将滚动历史消息页面的地址.
以/ mp / getmasssendmsg开头的URL是微信历史消息页面. 左侧的小锁表示此页面已通过https加密. 现在我们单击此行;
==========更新于2017年1月11日=========
一些以/ mp / getmasssendmsg开头的微信URL会将302跳转到以/ mp / profile_ext?action = home开头的地址. 因此,请点击此地址以查看内容.
如果html文件内容显示在右侧,则表示解密成功. 如果没有任何内容,请检查anyproxy操作模式是否具有参数i,是否生成了ca证书以及手机上是否正确安装了该证书.
现在,我们手机中的所有内容都可以以明文形式通过代理服务器. 接下来,我们需要修改代理服务器的配置,以便可以获得官方帐户的内容.
一个. 查找配置文件:
在Mac系统中配置文件的位置是/ usr / local / lib / node_modules / anyproxy / lib /;对于Windows系统,请原谅我不知道. 应该可以根据类似于mac的文件夹的地址找到此目录.
二,修改文件rule_default.js
找到replaceServerResDataAsync: 函数(req,res,serverResData,回调)函数
修改函数的内容(请仔细阅读注释,这里只是为了介绍原理,理解后根据自己的条件修改内容)
==========更新于2017年1月11日=========
由于存在两种页面格式,并且同一页面格式始终显示在不同的微信帐户中,但是为了与这两种页面格式兼容,以下代码将保留对这两种页面格式的判断. 您也可以在自己的页面表单中关注“删除li”
replaceServerResDataAsync: function(req,res,serverResData,callback){
if(/mp\/getmasssendmsg/i.test(req.url)){//当链接地址为公众号历史消息页面时(第一种页面形式)
if(serverResData.toString() !== ""){
try {//防止报错退出程序
var reg = /msgList = (.*?);\r\n/;//定义历史消息正则匹配规则
var ret = reg.exec(serverResData.toString());//转换变量为string
HttpPost(ret[1],req.url,"getMsgJson.php");//这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器
var http = require('http');
http.get('http://xxx.com/getWxHis.php', function(res) {//这个地址是自己服务器上的一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxHis.php的原理。
res.on('data', function(chunk){
callback(chunk+serverResData);//将返回的代码插入到历史消息页面中,并返回显示出来
})
});
}catch(e){//如果上面的正则没有匹配到,那么这个页面内容可能是公众号历史消息页面向下翻动的第二页,因为历史消息第一页是html格式的,第二页就是json格式的。
try {
var json = JSON.parse(serverResData.toString());
if (json.general_msg_list != []) {
HttpPost(json.general_msg_list,req.url,"getMsgJson.php");//这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器
}
}catch(e){
console.log(e);//错误捕捉
}
callback(serverResData);//直接返回第二页json内容
}
}
}else if(/mp\/profile_ext\?action=home/i.test(req.url)){//当链接地址为公众号历史消息页面时(第二种页面形式)
try {
var reg = /var msgList = \'(.*?)\';\r\n/;//定义历史消息正则匹配规则(和第一种页面形式的正则不同)
var ret = reg.exec(serverResData.toString());//转换变量为string
HttpPost(ret[1],req.url,"getMsgJson.php");//这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器
var http = require('http');
http.get('http://xxx.com/getWxHis', function(res) {//这个地址是自己服务器上的一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxHis.php的原理。
res.on('data', function(chunk){
callback(chunk+serverResData);//将返回的代码插入到历史消息页面中,并返回显示出来
})
});
}catch(e){
callback(serverResData);
}
}else if(/mp\/profile_ext\?action=getmsg/i.test(req.url)){//第二种页面表现形式的向下翻页后的json
try {
var json = JSON.parse(serverResData.toString());
if (json.general_msg_list != []) {
HttpPost(json.general_msg_list,req.url,"getMsgJson.php");//这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器
}
}catch(e){
console.log(e);
}
callback(serverResData);
}else if(/mp\/getappmsgext/i.test(req.url)){//当链接地址为公众号文章阅读量和点赞量时
try {
HttpPost(serverResData,req.url,"getMsgExt.php");//函数是后文定义的,功能是将文章阅读量点赞量的json发送到服务器
}catch(e){
}
callback(serverResData);
}else if(/s\?__biz/i.test(req.url) || /mp\/rumor/i.test(req.url)){//当链接地址为公众号文章时(rumor这个地址是公众号文章被辟谣了)
try {
var http = require('http');
http.get('http://xxx.com/getWxPost.php', function(res) {//这个地址是自己服务器上的另一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxPost.php的原理。
res.on('data', function(chunk){
callback(chunk+serverResData);
})
});
}catch(e){
callback(serverResData);
}
}else{
callback(serverResData);
}
},
上面的代码是使用anyproxy修改返回页面内容的功能,将脚本注入页面,然后将页面内容发送到服务器. 使用此原理可以分批采集官方帐户的内容和读取量. 此脚本中自定义了功能,下面将对其进行详细描述:
在rule_default.js文件的末尾添加以下代码: