免费获取:微信公众号批量爬取Java版
优采云 发布时间: 2020-09-06 17:21微信公众号批量抓取Java版本
最近,我们需要抓取微信公众号的文章信息。我在互联网上搜索后发现,抓取微信官方账号的困难在于无法在PC端打开官方账号文章的链接。您需要使用WeChat的浏览器(获取WeChat客户端的补充参数才能访问其他平台上的Open),这会给爬虫程序带来很多麻烦。后来,在知乎上,我看到了由一头大牛用PHP编写的微信官方帐户爬网程序,并且根据大佬的想法将其直接制成Java。在转换过程中遇到了很多详细的问题,因此请与大家分享。
系统的基本思想是在Android模拟器上运行微信,模拟器设置代理,通过代理服务器拦截微信数据,并将获取的数据发送到自己的程序进行处理。
要准备的环境:nodejs,anyproxy代理,Android*敏*感*词*
nodejs下载地址:我下载了Windows版本,只需下载并直接安装即可。安装后,直接运行C:\ Program Files \ nodejs \ npm.cmd即可自动配置环境。
anyproxy安装:在上一步中安装了nodejs之后,直接在cmd中运行npm install -g anyproxy,它将被安装
互联网上只有一个Android模拟器。
首先为代理服务器安装证书。默认情况下,Anyproxy不会解析https链接。安装证书后,可以解决它。在cmd中执行anyproxy --root将安装证书,然后必须在模拟器上下载证书。
然后输入anyproxy -i命令打开代理服务。 (请记住要添加参数!)
记住该IP和端口,然后Android*敏*感*词*的代理将使用此IP和端口。现在,使用浏览器打开网页:: 8002 /这是anyproxy的网络界面,用于显示http传输数据。
单击上方红色框中的菜单,将显示QR码。使用Android模拟器扫描代码以进行识别。*敏*感*词*(手机)将下载证书并安装。
现在我们准备为模拟器设置代理,代理模式设置为手动,代理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);此语句意味着直接将服务器响应数据返回给客户端。直接删除此语句,并将其替换为Daniel编写的以下代码。我在这里没有对代码做任何更改,并且内部的注释也很清楚地解释了,只需按照逻辑来理解它,问题就不大了。
1 replaceServerResDataAsync: function(req,res,serverResData,callback){
2 if(/mp\/getmasssendmsg/i.test(req.url)){//当链接地址为公众号历史消息页面时(第一种页面形式)
3 //console.log("开始第一种页面爬取");
4 if(serverResData.toString() !== ""){
try {//防止报错退出程序
7 var reg = /msgList = (.*?);/;//定义历史消息正则匹配规则
8 var ret = reg.exec(serverResData.toString());//转换变量为string
9 HttpPost(ret[1],req.url,"/InternetSpider/getData/showBiz");//这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器
10 var http = require('http');
11 http.get('http://xxx/getWxHis', function(res) {//这个地址是自己服务器上的一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxHis.php的原理。
12 res.on('data', function(chunk){
13 callback(chunk+serverResData);//将返回的代码插入到历史消息页面中,并返回显示出来
14 })
15 });
16 }catch(e){//如果上面的正则没有匹配到,那么这个页面内容可能是公众号历史消息页面向下翻动的第二页,因为历史消息第一页是html格式的,第二页就是json格式的。
17 //console.log("开始第一种页面爬取向下翻形式");
18 try {
19 var json = JSON.parse(serverResData.toString());
20 if (json.general_msg_list != []) {
21 HttpPost(json.general_msg_list,req.url,"/xxx/showBiz");//这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器
22 }
23 }catch(e){
24 console.log(e);//错误捕捉
25 }
26 callback(serverResData);//直接返回第二页json内容
27 }
28 }
29 //console.log("开始第一种页面爬取 结束");
30 }else if(/mp\/profile_ext\?action=home/i.test(req.url)){//当链接地址为公众号历史消息页面时(第二种页面形式)
31 try {
32 var reg = /var msgList = \'(.*?)\';/;//定义历史消息正则匹配规则(和第一种页面形式的正则不同)
33 var ret = reg.exec(serverResData.toString());//转换变量为string
34 HttpPost(ret[1],req.url,"/xxx/showBiz");//这个函数是后文定义的,将匹配到的历史消息json发送到自己的服务器
35 var http = require('http');
36 http.get('xxx/getWxHis', function(res) {//这个地址是自己服务器上的一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxHis.php的原理。
37 res.on('data', function(chunk){
38 callback(chunk+serverResData);//将返回的代码插入到历史消息页面中,并返回显示出来
39 })
40 });
41 }catch(e){
42 //console.log(e);
43 callback(serverResData);
44 }
45 }else if(/mp\/profile_ext\?action=getmsg/i.test(req.url)){//第二种页面表现形式的向下翻页后的json
46 try {
47 var json = JSON.parse(serverResData.toString());
48 if (json.general_msg_list != []) {
49 HttpPost(json.general_msg_list,req.url,"/xxx/showBiz");//这个函数和上面的一样是后文定义的,将第二页历史消息的json发送到自己的服务器
50 }
51 }catch(e){
52 console.log(e);
53 }
54 callback(serverResData);
55 }else if(/mp\/getappmsgext/i.test(req.url)){//当链接地址为公众号文章阅读量和点赞量时
56 try {
57 HttpPost(serverResData,req.url,"/xxx/getMsgExt");//函数是后文定义的,功能是将文章阅读量点赞量的json发送到服务器
58 }catch(e){
59
60 }
61 callback(serverResData);
62 }else if(/s\?__biz/i.test(req.url) || /mp\/rumor/i.test(req.url)){//当链接地址为公众号文章时(rumor这个地址是公众号文章被辟谣了)
63 try {
64 var http = require('http');
65 http.get('http://xxx/getWxPost', function(res) {//这个地址是自己服务器上的另一个程序,目的是为了获取到下一个链接地址,将地址放在一个js脚本中,将页面自动跳转到下一页。后文将介绍getWxPost.php的原理。
66 res.on('data', function(chunk){
67 callback(chunk+serverResData);
68 })
69 });
70 }catch(e){
71 callback(serverResData);
72 }
73 }else{
74 callback(serverResData);
75 }
76 //callback(serverResData);
77 }
这里是一个简短的解释。链接到微信官方帐户历史新闻页面的链接有两种形式:一种以/ mp / getmasssendmsg开头,另一种以/ mp / profile_ext开头。历史记录页面可以关闭。如果将其关闭,则会触发js事件,以发送请求以获取json数据(下一页内容)。也有指向官方帐户文章的链接,也有指向文章的阅读次数和喜欢次数的链接(返回json数据)。这些链接的形式是固定的,可以通过逻辑判断加以区分。这里的问题是,如果需要对所有历史页面进行爬网,该怎么做。我的想法是模拟鼠标在js中向下滑动,以触发提交请求以加载列表的下一部分。或者直接使用anyproxy分析滑动加载请求,并将请求直接发送至微信服务器。但是,如何判断没有剩余数据始终存在问题。我正在搜寻最新数据。我暂时没有这个要求。以后可能需要。如果需要,可以尝试一下。