微信公众号短链实时阅读量、点赞数爬虫(不会Hook可用)
众所周知,微信分享的公众号分享出的一般都是短链,在这个锻炼下使用浏览器打开并不能获取微信公众的阅读量点赞数等这些信息,如图1所示。

但是实际拥有详细信息的则是这个链接下面,提取链接所需要提交的信息包括经过本人筛选有以下参数,并且携带Cookie,如图2所示:

其中_biz、mid、sn会根据不同的文章发生变动,其余的都是固定值,但都可以从原始连接中取得,且原始链接可以通过F12在谷歌浏览器前端获取,如图3所示:

所以我们现在就应当编写获取真是链接代码:
private String GetRealAddress(String url) throws IOException {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpGet httpGet = new HttpGet(url);
/// 解析html字符串
HttpResponse response = httpClient.execute(httpGet);
String html = EntityUtils.toString(response.getEntity());
Document doc = Jsoup.parse(html);
/// 获取GET参数
String realUrl = doc.select("meta[property='og:url']").attr("content");
//获取真实链接
httpClient.close();
return new URL(realUrl).getQuery();
}
根据Fiddler软件抓包可以知道,阅读数等详细信息是在 https://mp.weixin.qq.com/mp/getappmsgext/...下,而要携带参数我们已经可以从真实长链中获取。别看图2的请求链接好像很长,但是实质上如果只是为了获取阅读量、点赞数等一些有用信息,只需要带上appmsg_token即可,如图4所示:

既然请求链接和请求参数我们都知道,那么就可以书写代码了:
public AjaxResponse getNumberNewWay(String url) throws IOException {
String realUrl = this.GetRealAddress(url);
if (StringUtils.hasText(realUrl)) {
// 使用分隔符 "&" 将参数字符串分割成参数对
String[] parameterPairs = realUrl.split("&");
// 创建一个 Map 来存储参数名和参数值
Map<String, String> parameterMap = new HashMap<>();
// 遍历参数对,提取参数名和参数值,并放入 Map 中
for (String parameterPair : parameterPairs) {
String[] parts = parameterPair.split("=");
if (parts.length == 2) {
String paramName = parts[0];
String paramValue = parts[1];
parameterMap.put(paramName, paramValue);
}
}
// 获取各个参数的值,因为上面使用"=="分割,所以biz的值后面的“==”也会被分割
String biz = parameterMap.get("__biz") + "==";
String mid = parameterMap.get("mid");
String idx = parameterMap.get("idx");
String sn = parameterMap.get("sn");
String appmsgToken = "";
if (StringUtils.hasText(cookie)){
//获取appmsgToken
String[] parts = cookie.split(";");
for (String part : parts) {
if (part.startsWith("appmsg_token=")) {
appmsgToken = part.substring("appmsg_token=".length());
break;
}
}
}else {
return AjaxResponse.error("cookie缺失");
}
String originUrl = "https://mp.weixin.qq.com/mp/getappmsgext?";
String postUrl = originUrl + "appmsg_token=" + appmsgToken + "&x5=0";
HttpPost httpPost = new HttpPost(postUrl);
//模拟微信客户端
httpPost.setHeader("User-Agent", "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0Chrome/57.0.2987.132 MQQBrowser/6.2 Mobile");
httpPost.setHeader("Cookie", cookie);
httpPost.setHeader("Origin", "https://mp.weixin.qq.com");
//httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");
CloseableHttpClient client = HttpClientBuilder.create().build();
List<NameValuePair> parameters = new ArrayList<>();
parameters.add(new BasicNameValuePair("is_only_read", "1"));
parameters.add(new BasicNameValuePair("is_temp_url", "0"));
parameters.add(new BasicNameValuePair("appmsg_type", "9"));
parameters.add(new BasicNameValuePair("__biz", biz));
parameters.add(new BasicNameValuePair("mid", mid));
parameters.add(new BasicNameValuePair("idx", idx));
parameters.add(new BasicNameValuePair("sn", sn));
HttpEntity entity = new UrlEncodedFormEntity(parameters,"utf-8");
httpPost.setEntity(entity);
// 发送请求并获取响应
try {
HttpResponse response = client.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
String StringResult = EntityUtils.toString(responseEntity);
// 创建一个 ObjectMapper 对象
ObjectMapper objectMapper = new ObjectMapper();
JsonNode jsonNode = objectMapper.readTree(StringResult);
// 提取 read_num 的值
JsonNode readJson = jsonNode.get("appmsgstat");
if (readJson != null) {
return AjaxResponse.success(readJson.get("read_num").asText());
}
return AjaxResponse.error("获取阅读量失败,请检查token是否过期");
} catch (IOException e) {
e.printStackTrace();
return AjaxResponse.error("远程调用失败");
}
}
return AjaxResponse.error("获取真实地址失败");
}
这里存在一个时效性的问题,由于微信设置的Cookie有时效性,且是由微信客户端自身生成,并且笔者不会Hook。所以就想到了一个另类的办法:通过定时任务刷新微信文章来刷新Cookie->利用Fidder拦截请求获取Cookie->Cookie传入Java代码中获取信息。
由于不会Hook,所以笔者就用了python的pyautogui与cv2库识别微信浏览器的刷新图标,然后定时进行刷新,大体流程是:截一张桌面图像->识别刷新图标位置->鼠标模拟刷新。python核心代码如下:
def refresh_funtion():
# 截一张桌面新的图片
newImg = pyautogui.screenshot()
newImg.save('C:\\Users\\chen\\Desktop\\newAll.png')
# 转换为OpenCV的图像格式
newImg_cv = cv2.cvtColor(cv2.imread('C:\\Users\\chen\\Desktop\\newAll.png'), cv2.COLOR_BGR2RGB)
# 寻找刷新按钮
# 如果文本框已经打开则进行刷新
refreshTemplate = cv2.imread('C:\\Users\\chen\\Desktop\\refresh.jpg')
# 在屏幕截图中搜索目标图像
refreshRes = cv2.matchTemplate(newImg_cv, refreshTemplate, cv2.TM_CCOEFF_NORMED)
# 获取匹配度最高的位置
refresh_min_val, refresh_max_val, refresh_min_loc, refresh_max_loc = cv2.minMaxLoc(refreshRes)
# 如果存在则刷新
# 如果匹配度最高的位置的阈值大于 0.8,则模拟鼠标点击
if refresh_max_val > 0.8:
# 计算鼠标点击的位置
x, y = refresh_max_loc[0] + refreshTemplate.shape[1] // 2, refresh_max_loc[1] + refreshTemplate.shape[0] // 2
# 模拟鼠标点击
pyautogui.click(x, y)
这里就需要使用FiddlerScript脚本,在Fiddler软件的FidderScipt中的OnBeforRequest方法内插入图5中代码,将刷新的Cookie传递到Java代码中,再让Java代码根据传递到的Cookie解析并获取微信信息,如图5所示:

本方法仅提供不会Hook的同学的权宜之计,仅供学习参考使用,不可用于违法途径。
微信公众号短链实时阅读量、点赞数爬虫(不会Hook可用)的更多相关文章
- 做App还是微信公众号,你该如何抉择?
我不够聪明,因为我经常出于好奇被自己提出的问题所困扰,于是乎就有些强迫症似的拼命去寻求答案——我只是想说服自己,让自己从困扰的谜团中清醒.坚定方向,进而能从容不迫的走下去... 最近在考虑一个问题:做 ...
- 使用signalr实现网页和微信公众号实时聊天(上)
最近项目中需要实现客户在公众号中和客服(客服使用后台网站系统)进行实时聊天的功能.折腾了一段时间,实现了这个功能.现在将过程记录下,以便有相同需求的同行可以参考,也是自己做个总结.这篇是上,用手机编辑 ...
- 我推荐阅读的微信公众号-IT类
微信,正深刻影响着我们的生活,每个使用微信的人,从微信这个窗口去了解这个世界. 微信公众号,微信生态圈是核心功能之一,每天都有大量的文章创作.传播.转发出来,海量的信息扑面而来,微信阅读成为微信使用者 ...
- 你所不知道的 Kindle - 阅读微信公众号文章
Kindle 是一款非常优秀的阅读设备,它为我们提供了非常舒服的阅读体验,并且配合强大的亚马逊图书资源,应该是目前最好的阅读设备之一.Kindle 在已有的成就下还一直在努力提升用户体验.为中国用户开 ...
- 微信公众号 & 付费阅读
微信公众号 & 付费阅读 付费功能 付费阅读 付费功能使用说明 1.付费功能介绍 开通了付费功能的公众号,运营者可以在编辑时对原创文章的部分或全部内容设置收费.对于付费图文,用户未付费前可免费 ...
- 微信公众号批量爬取java版
最近需要爬取微信公众号的文章信息.在网上找了找发现微信公众号爬取的难点在于公众号文章链接在pc端是打不开的,要用微信的自带浏览器(拿到微信客户端补充的参数,才可以在其它平台打开),这就给爬虫程序造成很 ...
- 第三方网站不能调用微信公众平台里的图片了 显示"此图片来自微信公众号平台未经允许不可引用"
下午ytkah在自己小博客搜索时看到有几篇文章图片显示不了,再访问一些网站时发现有些图片无法显示出来,显示"此图片来自微信公众号平台未经允许不可引用",如下图所示,这个应该是最近微 ...
- flask开发微信公众号
1.进入微信公众号首页,进行注册登录 https://mp.weixin.qq.com/ 2.进入个人首页,进行公众号设置 可参照 公众号文档 进行开发 开发前 先阅读 接口权限列表 3.配置服务器 ...
- pc端引入微信公众号文章
最近做了一个小需求,结果坑特别多..... 需求是这样的,要给公司内部做一个微信公众号广告投票系统,整个项目就不多赘述了,有个小功能,要求是这样的: 点击某条记录后的“投票”按钮,在当前页面弹出弹窗显 ...
- NodeJs 开发微信公众号(四)微信网页授权
微信的网页授权指的是在微信公众号中访问第三方网页时获取用户地理.个人等信息的权限.对于开发了自己的网页app应用时,获取个人的信息非常重要.上篇博客讲到了注册时可以获取用户的信息,很多人会问为什么还需 ...
随机推荐
- MySQL-防止误删除的方案就是删除,看不见岂不就是删除了吗,所以就是把它隐藏起来。
版权声明:原创作品,谢绝转载!否则将追究法律责任. ----- 作者:kirin 伪删除: 用update替代delete 1.添加状态列 ALTER TABLE student2 ADD state ...
- 【Android】实现连接SQLite并尝试进行增删改查
- windows下tomcat开机自启动
在Windows下,可以通过以下步骤将Tomcat设置为开机自启动: 1. 打开Tomcat安装目录:通常情况下,Tomcat的安装目录位于`C:\Program Files\Apache Softw ...
- Python批量改文件名
对以下路径中的文件名批量修改. 一.读取指定路径中的文件名 #导入标准库 import os #读取文件名 filesDir = "路径--" fileNameList = os. ...
- Vs code创建项目教程
1.首先,vscode本身没有新建项目的选项,所以要先创建一个空的文件夹. 2.然后打开vscode,再在vscode里面打开文件夹,这样才可以创建项目. 3.选择一个空文件夹. 4.Ctrl+shi ...
- 文心一言 VS 讯飞星火 VS chatgpt (150)-- 算法导论12.2 6题
六.用go语言,考虑一棵二叉搜索树 T ,其关键字互不相同.证明:如果 T 中一个结点 x 的右子树为空,且 x 有一个后继 y ,那么 y 一定是 x 的最底层祖先,并且其左孩子也是 x 的祖先.( ...
- [AGC038E] Gachapon
Problem Statement Snuke found a random number generator. It generates an integer between $0$ and $N- ...
- springBoot——整合junit
spring整合junit复习 springBoot整合junit package com.example.springboot_04; import com.example.springboot_0 ...
- python 实现一个简单的计算器
python 实现一个简单的计算器 本文主要整合下tkinter ,实现下简单的计算器. 代码如下: #!/usr/bin/python3 # -*- coding: UTF-8 -*- " ...
- 如何用axios加后端数据库传值给前端
小杰笔记: 如何用axios : 第一步:编写数据库实体类 @Data @AllArgsConstructor @NoArgsConstructor public class User { priva ...