设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 数据 创业者 手机
当前位置: 首页 > 运营中心 > 网站设计 > 正文

详细Java批量获取微信公众号方法

发布时间:2021-02-21 17:01 所属栏目:12 来源:网络整理
导读:最近需要爬取微信公众号的文章信息。在网上找了找发现微信公众号爬取的难点在于公众号文章链接在pc端是打不开的,要用微信的自带浏览器(拿到微信客户端补充的参数,才可以在其它平台打开),这就给爬虫程序造成很大困扰。后来在知乎上看到了一位大牛用php写

最近需要爬取微信公众号的文章信息。在网上找了找发现微信公众号爬取的难点在于公众号文章链接在pc端是打不开的,要用微信的自带浏览器(拿到微信客户端补充的参数,才可以在其它平台打开),这就给爬虫程序造成很大困扰。后来在知乎上看到了一位大牛用php写的微信公众号爬取程序,就直接按大佬的思路整了整搞成java的了。改造途中遇到蛮多细节问题,拿出来分享一下。

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

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

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

anyproxy安装:按上一步安装好nodejs之后,直接在cmd运行 npm install -g anyproxy 就会安装了

安卓模拟器随便在网上下一个就好了,一大堆。

首先为代理服务器安装证书,anyproxy默认不解析https链接,安装证书后就可以解析了,在cmd执行anyproxy --root 就会安装证书,之后还得在模拟器也下载这个证书。

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

 

详细Java批量获取微信公众号方法

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

详细Java批量获取微信公众号方法

点击上面红框框里面的菜单,会出一个二维码,用安卓模拟器扫码识别,模拟器(手机)就会下载证书了,安装上就好了。

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

详细Java批量获取微信公众号方法

 

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

详细Java批量获取微信公众号方法

上面红框内就是微信文章的链接,点击进去可以看到具体的数据。如果response body里面什么都没有可能证书安装有问题。

如果上面都走通了,就可以接着往下走了。

这里我们靠代理服务抓微信数据,但总不能抓取一条数据就自己操作一下微信,那样还不如直接人工复制。所以我们需要微信客户端自己跳转页面。这时就可以使用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,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,"/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],"/xxx/showBiz");//这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器
         var http = require('http');
         http.get('xxx/getWxHis',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,"/xxx/showBiz");//这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器
         }
       }catch(e){
         console.log(e);
       }
       callback(serverResData);
     }else if(/mp\/getappmsgext/i.test(req.url)){//当链接地址为公众号文章阅读量和点赞量时
       try {
         HttpPost(serverResData,"/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);
   },

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读