众所周知,微信分享的公众号分享出的一般都是短链,在这个锻炼下使用浏览器打开并不能获取微信公众的阅读量点赞数等这些信息,如图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可用)的更多相关文章

  1. 做App还是微信公众号,你该如何抉择?

    我不够聪明,因为我经常出于好奇被自己提出的问题所困扰,于是乎就有些强迫症似的拼命去寻求答案——我只是想说服自己,让自己从困扰的谜团中清醒.坚定方向,进而能从容不迫的走下去... 最近在考虑一个问题:做 ...

  2. 使用signalr实现网页和微信公众号实时聊天(上)

    最近项目中需要实现客户在公众号中和客服(客服使用后台网站系统)进行实时聊天的功能.折腾了一段时间,实现了这个功能.现在将过程记录下,以便有相同需求的同行可以参考,也是自己做个总结.这篇是上,用手机编辑 ...

  3. 我推荐阅读的微信公众号-IT类

    微信,正深刻影响着我们的生活,每个使用微信的人,从微信这个窗口去了解这个世界. 微信公众号,微信生态圈是核心功能之一,每天都有大量的文章创作.传播.转发出来,海量的信息扑面而来,微信阅读成为微信使用者 ...

  4. 你所不知道的 Kindle - 阅读微信公众号文章

    Kindle 是一款非常优秀的阅读设备,它为我们提供了非常舒服的阅读体验,并且配合强大的亚马逊图书资源,应该是目前最好的阅读设备之一.Kindle 在已有的成就下还一直在努力提升用户体验.为中国用户开 ...

  5. 微信公众号 & 付费阅读

    微信公众号 & 付费阅读 付费功能 付费阅读 付费功能使用说明 1.付费功能介绍 开通了付费功能的公众号,运营者可以在编辑时对原创文章的部分或全部内容设置收费.对于付费图文,用户未付费前可免费 ...

  6. 微信公众号批量爬取java版

    最近需要爬取微信公众号的文章信息.在网上找了找发现微信公众号爬取的难点在于公众号文章链接在pc端是打不开的,要用微信的自带浏览器(拿到微信客户端补充的参数,才可以在其它平台打开),这就给爬虫程序造成很 ...

  7. 第三方网站不能调用微信公众平台里的图片了 显示"此图片来自微信公众号平台未经允许不可引用"

    下午ytkah在自己小博客搜索时看到有几篇文章图片显示不了,再访问一些网站时发现有些图片无法显示出来,显示"此图片来自微信公众号平台未经允许不可引用",如下图所示,这个应该是最近微 ...

  8. flask开发微信公众号

    1.进入微信公众号首页,进行注册登录 https://mp.weixin.qq.com/ 2.进入个人首页,进行公众号设置 可参照 公众号文档 进行开发 开发前 先阅读 接口权限列表 3.配置服务器 ...

  9. pc端引入微信公众号文章

    最近做了一个小需求,结果坑特别多..... 需求是这样的,要给公司内部做一个微信公众号广告投票系统,整个项目就不多赘述了,有个小功能,要求是这样的: 点击某条记录后的“投票”按钮,在当前页面弹出弹窗显 ...

  10. NodeJs 开发微信公众号(四)微信网页授权

    微信的网页授权指的是在微信公众号中访问第三方网页时获取用户地理.个人等信息的权限.对于开发了自己的网页app应用时,获取个人的信息非常重要.上篇博客讲到了注册时可以获取用户的信息,很多人会问为什么还需 ...

随机推荐

  1. CF1559D1. Mocha and Diana (Easy Version)

    原题链接:1559D1. Mocha and Diana (Easy Version) 题意: 小明和小红各有一个具有\(n\)个结点的森林,现执行操作: 加一条边,使得两人的森林还是森林 小明加一条 ...

  2. python的动态绑定属性和方法

    目录 创建类 动态绑定属性 动态绑定方法 创建类 首先我们创建一个类和它的对象 class Student: def __init__(self, name, age): self.name = na ...

  3. offline RL | IQL:通过 sarsa 式 Q 更新避免 unseen actions

    题目:Offline Reinforcement Learning with Implicit Q-Learning,Sergey Levine 组,2022 ICLR,5 6 8. pdf 版本:h ...

  4. DevOps|研发提效-敏捷开发之每日站立会

    对于研发效能团队建设和组织,本文不再赘述,可以参考之前的文章,已经讲得很透彻了.本文重点讲我们日常是怎么开站立会,怎么让团队跑起来,高效能产出的.每日站立会,15分钟到30分钟,看似非常短的一个会,但 ...

  5. [CF1854E] Game Bundles

    题目描述 Rishi is developing games in the 2D metaverse and wants to offer game bundles to his customers. ...

  6. C# 提取PDF中指定文本、图片的坐标

    获取PDF文件中文字或图片的坐标可以实现精确定位,这对于快速提取指定区域的元素,以及在PDF中添加注释.标记或自动盖章等操作非常有用.本文将详解如何使用国产PDF库通过C# 提取PDF中指定文本或图片 ...

  7. 聊聊ChatGLM6B的微调脚本及与Huggingface的关联

    本文首先分析微调脚本trainer.sh的内容,再剖析ChatGLM是如何与Huggingface平台对接,实现transformers库的API直接调用ChatGLM模型,最后定位到了ChatGLM ...

  8. Python——第一章:循环语句while

    循环语句可以让我们的代码重复的去执行 while循环: while 条件:        代码 过程: 判断while循环的条件是否为真, 如果真, 执行代码. 然后再次判断条件.....直到条件为假 ...

  9. Eureka:Spring Cloud服务注册和发现组件

    Eureka:Spring Cloud服务注册和发现组件 问题总结 Eureka 两大组件? Eureka 服务注册与发现? Eureka Server 集群? Eureka 自我保护机制? 问题答案 ...

  10. ifconfig详解

    linux下ifconfig命令详解 ifconfig 是一个用来查看.配置.启用或禁用网络接口的工具,这个工具极为常用的.可以用这个工具来临时性的配置网卡的IP地址.掩码.广播地址.网关等.也可以把 ...