众所周知,微信分享的公众号分享出的一般都是短链,在这个锻炼下使用浏览器打开并不能获取微信公众的阅读量点赞数等这些信息,如图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. Codeforces Round #700 (Div. 2) A~C题解

    写在前边 链接:Codeforces Round #699 (Div. 2) A. Yet Another String Game 链接:A题链接 题目大意: 给定一个字符串,有两位同学来操作这个字符 ...

  2. python,opencv-python人脸识别,并且发邮件对镜头前未知人员进行报警

    我们在任意一个硬盘的根目录下创建一个Code-project文件夹 在该文件夹下分别创建C-project和Python-project文件夹 在Python-project文件夹下创建face re ...

  3. MySQL锁粒度是什么意思?MySQL锁粒度是什么?

    MySQL锁粒度就是我们通常所说的锁级别.数据库引擎具有多粒度锁定,允许一个事务锁定不同类型的资源. MySQL数据库有三种锁的级别,分别是:页级锁.表级锁 .行级锁. 锁粒度 锁粒度就是我们通常所说 ...

  4. 有什么BI工具可以实现中国式报表?

    BI(Business Intelligence)工具是指用于帮助企业收集.分析.处理和展示数据的软件工具,以支持企业决策制定和业务运营优化的技术系统. 中国式报表在BI工具中的实现主要涉及到对中国商 ...

  5. Netty内置的http报文解码流程

    netty解码 netty通过内置处理器HttpRequestDecoder和HttpObjectAggregator对Http请求报文进行解码之后,Netty会将Http请求封装成一个FullHtt ...

  6. [ABC265C] Belt Conveyor

    Problem Statement We have a grid with $H$ horizontal rows and $W$ vertical columns. $(i, j)$ denotes ...

  7. 设备唯一标识方法(Unique Identifier):如何在 Windows 系统上获取设备的唯一标识

    原文地址 设备唯一标识方法(Unique Identifier):如何在 Windows 系统上获取设备的唯一标识 zz 唯一的标识一个设备是一个基本功能,可以拥有很多应用场景,比如软件授权(如何保证 ...

  8. 机器人行业数据闭环实践:从对象存储到 JuiceFS

    JuiceFS 社区聚集了来自各行各业的前沿科技用户.本次分享的案例来源于刻行,一家商用服务机器人领域科技企业. 商用服务机器人指的是我们日常生活中常见的清洁机器人.送餐机器人.仓库机器人等.刻行采用 ...

  9. MySQL运维10-Mycat分库分表之一致性哈希分片

    一.一致性哈希分片 一致性哈希分片的实现思路和我们之前介绍的水平分表中的取模分片是类似的.只不过取模分片,采用的是利用主键和分片数进行取模运算,然后根据取模后的结果,将数据写入到不同的分片数据中.但是 ...

  10. 痞子衡嵌入式:简析i.MXRT1170 MECC64功能特点及其保护片内OCRAM1,2之道

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1170 MECC64功能特点及其保护片内OCRAM1,2之道. ECC是 "Error Correcting C ...