微信文章自动采集软件(微信公众号爬取程序分享搞成java的难点在于)

优采云 发布时间: 2022-01-17 17:22

  微信文章自动采集软件(微信公众号爬取程序分享搞成java的难点在于)

  最近需要爬取微信公众号的文章信息。我在网上搜索,发现爬取微信公众号的难点在于公众号文章的链接在PC端打不开,所以需要使用微信自带的浏览器(获取参数辅以微信客户端,只能在其他平台打开),给爬虫带来了很大的麻烦。后来在知乎上看到一个大牛用php写的微信公众号爬虫程序,直接按照大佬的思路做成了java。改造过程中遇到了很多细节和问题,就分享给大家。

  系统的基本思路是在Android模拟器上运行微信,在模拟器上设置代理,通过代理服务器截取微信数据,将获取到的数据发送给自己的程序进行处理。

  需要准备的环境:nodejs、anyproxy代理、安卓模拟器

  Nodejs下载地址:我下载的是windows版本的,直接安装就好了。安装后直接运行 C:\Program Files\nodejs\npm.cmd 会自动配置环境。

  anyproxy安装:按照上一步安装nodejs后,直接在cmd中运行npm install -g anyproxy即可安装

  网上的安卓模拟器就好了,有很多。

  首先安装代理服务器的证书。Anyproxy 默认不解析 https 链接。安装证书后,就可以解析了。在cmd中执行anyproxy --root安装证书,然后在模拟器中下载证书。

  然后输入anyproxy -i 命令打开代理服务。(记得添加参数!)

  

  记住这个ip和端口,那么安卓模拟器的代理就会用到这个。现在用浏览器打开网页::8002/ 这是anyproxy的网页界面,用来显示http传输的数据。

  

  点击上方红框中的菜单,会出现一个二维码。用安卓模拟器扫码识别。模拟器(手机)会下载证书并安装。

  现在准备为模拟器设置代理,代理模式设置为手动,代理ip为运行anyproxy的机器的ip,端口为8001

  

  准备工作到这里基本完成。在模拟器上打开微信,打开一个公众号的文章,就可以从刚刚打开的web界面看到anyproxy抓取的数据:

  

  上图红框是微信文章的链接,点击查看具体数据。如果响应正文中没有任何内容,则可能是证书安装有问题。

  如果顶部清晰,您可以向下。

  这里我们依靠代理服务来抓取微信数据,但是我们不能抓取一条数据自己操作微信,所以还是手动复制比较好。所以我们需要微信客户端自己跳转到页面。这时可以使用anyproxy拦截微信服务器返回的数据,将页面跳转代码注入其中,然后将处理后的数据返回给模拟器,实现微信客户端的自动跳转。

  在anyproxy中打开一个名为rule_default.js的js文件,windows下的文件为:C:\Users\Administrator\AppData\Roaming\npm\node_modules\anyproxy\lib

  文件中有一个方法叫做replaceServerResDataAsync: function(req,res,serverResData,callback)。该方法负责对anyproxy获取的数据进行各种操作。开头应该只有 callback(serverResData) ;该语句的意思是直接将服务器响应数据返回给客户端。直接把这条语句删掉,换成下面大牛写的代码。这里的代码我没有做任何改动,里面的注释也解释的很清楚。顺着逻辑去理解就好,问题不大。

  

replaceServerResDataAsync: function(req,res,serverResData,callback){

if(/mp\/getmasssendmsg/i.test(req.url)){//当链接地址为公众号历史消息页面时(第一种页面形式)

//console.log("开始第一种页面爬取");

if(serverResData.toString() !== ""){

6 try {//防止报错退出程序

var reg = /msgList = (.*?);/;//定义历史消息正则匹配规则

var ret = reg.exec(serverResData.toString());//转换变量为string

HttpPost(ret[1],req.url,"/InternetSpider/getData/showBiz");//这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器

var http = require('http');

http.get('http://xxx/getWxHis', function(res) {//这个地址是自己服务器上的一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxHis.php的原理。

res.on('data', function(chunk){

callback(chunk+serverResData);//将返回的代码插入到历史消息页面中,并返回显示出来

})

});

}catch(e){//如果上面的正则没有匹配到,那么这个页面内容可能是公众号历史消息页面向下翻动的第二页,因为历史消息第一页是html格式的,第二页就是json格式的。

//console.log("开始第一种页面爬取向下翻形式");

try {

var json = JSON.parse(serverResData.toString());

if (json.general_msg_list != []) {

HttpPost(json.general_msg_list,req.url,"/xxx/showBiz");//这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器

}

}catch(e){

console.log(e);//错误捕捉

}

callback(serverResData);//直接返回第二页json内容

}

}

//console.log("开始第一种页面爬取 结束");

}else if(/mp\/profile_ext\?action=home/i.test(req.url)){//当链接地址为公众号历史消息页面时(第二种页面形式)

try {

var reg = /var msgList = \'(.*?)\';/;//定义历史消息正则匹配规则(和第一种页面形式的正则不同)

var ret = reg.exec(serverResData.toString());//转换变量为string

HttpPost(ret[1],req.url,"/xxx/showBiz");//这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器

var http = require('http');

http.get('xxx/getWxHis', function(res) {//这个地址是自己服务器上的一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxHis.php的原理。

res.on('data', function(chunk){

callback(chunk+serverResData);//将返回的代码插入到历史消息页面中,并返回显示出来

})

});

}catch(e){

//console.log(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,"/xxx/showBiz");//这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器

}

}catch(e){

console.log(e);

}

callback(serverResData);

}else if(/mp\/getappmsgext/i.test(req.url)){//当链接地址为公众号文章阅读量和点赞量时

try {

HttpPost(serverResData,req.url,"/xxx/getMsgExt");//函数是后文定义的,功能是将文章阅读量点赞量的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/getWxPost', function(res) {//这个地址是自己服务器上的另一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxPost.php的原理。

res.on('data', function(chunk){

callback(chunk+serverResData);

})

});

}catch(e){

callback(serverResData);

}

}else{

callback(serverResData);

}

//callback(serverResData);

},

  这是一个简短的解释。微信公众号历史新闻页面的链接有两种形式:一种以/mp/getmasssendmsg开头,另一种以/mp/profile_ext开头。历史页面可以向下滚动。向下滚动会触发js事件发送请求获取json数据(下一页的内容)。还有公众号文章的链接,以及文章的阅读和点赞链接(返回json数据)。这些环节的形式是固定的,可以通过逻辑判断加以区分。这里有个问题,如果历史页面需要一路爬取怎么办。我的想法是通过js模拟鼠标向下滑动,从而触发请求提交下一部分列表的加载。或者直接使用anyproxy分析下载请求,直接向微信服务器发出这个请求。但是有一个问题是如何判断没有剩余数据。我正在抓取最新数据。我暂时没有这个要求,但以后可能需要。如果需要,您可以尝试一下。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线