背景:
公司的产品大佬想做一个基于rss爬取热点文章的运营工具,爬取的文章经过审核、清洗后投放在app上增加用户黏性。
和运营同学勾兑后了解到目前她们获取热点的来源主要是微信公众号,于是一期主要解决微信公众号文章的爬取问题。
Rss Hub
Rss Hub 是一个生成rss feed的工具,生成的rss feed添加到rss client后即可订阅。
Rss Hub文档里面列举了一些公众号的源,但是由于微信的反爬策略严格,均已失效。
造轮子
既然现成的轮子不能用,那我们就另辟蹊径(zao lun zi)。
先贴整体的流程图:
通过过mac微信打开公众号消息列表进行抓包,可以抓到这三个主要的接口:
https://mp.weixin.qq.com/mp/getmasssendmsg?
__biz
=1&uin
=2&key
=3&devicetype=iMac+MacBookPro14%2C1+OSX+OSX+10.14.3+build(18D42)&version=12040112&lang=zh_CN&nettype=WIFI&ascene=3&fontScale=100&pass_ticket=4每次点击查看公众号历史消息打开的新窗口就是这个链接。注意到链接里面有几个重要的参数:
__biz
公众号iduin
猜测是用户id,同一用户不变key
一个带expire的token,查阅网上的说法以前可以通过 getA8Key 生成万能key,但是已经失效。抓包也找不到这个key更新下发的请求,猜测使用了私密协议传输
https://mp.weixin.qq.com/mp/profile_ext?action=getmsg&
__biz
=1&f=json&offset
=0&count
=10&is_ok=1&scene=124&uin
=2&key
=3&pass_ticket=&wxtoken=&appmsg_token=&x5=0&f=json这是微信公众号历史消息列表的分页接口。有几个重要的参数:
__biz
uin
key
offset
偏移量count
页容量,试过更改这个字段为一个很大的值尝试一次性拉取所有文章,但是返回的内容无变化,猜测有内部策略。微信客户端的默认值是10,我们循环捞取直到返回的can_msg_continue
不为1即可
hexo markdown对Apple Script的支持不好,没有语法高亮。source code可以到gist上看:dennisleung/利用Apple Script爬取微信公众号历史文章
Step 1
这个方案的难点是怎么实现定时自动点击公众号,这段时间刚好在研究mac自动化,于是用Apple Script写了一个定时点击关注公众号列表的程序。
要注意的一个点是尝试直接用Apple Script去点击微信的某个UI元素时会出现missing value
,stack exchange上也有类似的问题:
How do I make the mouse click at current location using AppleScript? 。
回复里面有一个大佬提供一个MouseTools
的工具,可以通过命令行模拟鼠标操作。因此我们只要保证微信窗口在顶层,获取想要点击的UI元素的坐标,再通过Apple Script执行MouseTools即可。
直接上源码:
Step 2
通过配置全局代理,微信的请求会被转发到whistle上。结合whistle的auto-save插件对getmasssendmsg请求log自动保存。然后通过一个定时脚本从最新的log中解析出__biz、uin、key落地即可。
1 | //解析log,更新key |
Step 3
有了必要的凭证,最后循环请求分页接口获取列表:
1 | //分页爬取公众号消息列表 |
Apple Script相关学习资料
拓展
这里利用了Apple Script模拟点击Mac微信客户端的方法获取最新的访问凭证,类似的可以在移动端用Appium、Monkey之类的工具实现类似的功能(公司之前有个爬取微信指数的工具用的就是Appium实现),后面可以再研究研究。
这类自动化工具对一些自动化的e2e集成测试应该是大有裨益的~