免费获取:微信公众号批量爬取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分析滑动加载请求,并将请求直接发送至微信服务器。但是,如何判断没有剩余数据始终存在问题。我正在搜寻最新数据。我暂时没有这个要求。以后可能需要。如果需要,可以尝试一下。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线