微信公众号现已成为主流的一对多媒体行为活动,也是现在互联网内容生产不可忽视的一股力量。
在此基础上,微信公众号爬虫变得很有价值,对内容生产型公众号进行数据挖掘可以得到很多有意思、有价值的信息。就我所知,可用于微信公众号爬虫的方式主要有以下几种:web微信,手机客户端抓包,搜狗微信入口,appium自动化测试,Xposed框架等。
其中,web微信只能被动接受公众号消息,不能主动去查阅微信公众号历史消息。由此,可以通过itchat,wxpy等web微信库来编写一个机器人,实时接收微信推送,适用于需要实时更新微信推送消息的场景需求。但此方法有个弊端,首先要保证手机上自己的微信不经常断网掉线,才能使机器人长时间在线。再者,用这些第三方库长时间登陆或频繁的登陆web微信,或被封号,要是微信小号很多,可以尝试这个方法。
手机客户端抓包,利用fiddler或charles等抓包工具,算是一个比较主流(我自己感觉的orz),效率较高的方法,可以快速的抓取微信公众号信息和历史消息,此方法也有弊端:cookies失效快,半天差不多的时间吧,有针对性的去抓取某几个公众号的历史消息也是可以的。要想通过模拟登陆微信自动获得cookies,好像挺难的,小弟愚钝,无法实现,貌似微信登陆是tcp协议?
搜狗微信入口与其他相比显得友好的多。应该是微信搜索引擎和搜狗有合作吧,所以搜狗能有微信搜索的入口。搜狗微信有两个类型,一是通过关键词搜索文章,二是通过关键词搜索公众号,并且搜索到的微信号只能获得其最近十条消息推送(即意味着无法通过此方法爬取指定公众号历史消息)。这个方法还是有一些应用场景的,比如像获取关于某个关键词的大量文章,比如做一个定时任务,或间隔一定时间去爬取某个微信公众号最新十条推送来获取其最新推送,这一点上,比web微信要好得多,搜狗微信的更新也是实时的,直接和mp.weixin.qq.com相关联。
appium自动化和Xposed框架我了解不多。appium类似于selenium,在移动端做自动化测试的,模拟点击即可。Xposed框架就有很多可以搞的了,Xposed可以在不修改apk的情况下做到一些额外的功能,爬虫自然是可以的,除此之外可做到以自动抢红包,自动回复机器人,修改微信步数等等骚操作。
写爬虫也有一段时间了,个人感觉实现爬虫除了反反爬,爬虫效率外,还有一个很难实现的地方就是爬虫的稳定性,健壮性,需要考虑到很多异常情况,以及合理有效的异常处理,在这一点上,我觉得我还需要向各大爬虫大佬学习。(感觉自己瞎扯了好多,还没有开始我的正文(orz),感觉嫌我啰嗦的大佬请别生气。)
利用搜狗微信写一个爬虫接口,代码很简陋,只有两百行不到的代码。(这里我还得吐槽一下,python写多了,总有一种自己很叼,编程很简单的错觉,几行代码就能实现很厉害的功能,这时候需要去写写CPP冷静一下,让自己知道什么是真正的编程。)
以下记录下我写这个爬虫接口脚本的过程:
1. 页面请求分析(以公众号搜索为例):
可以看到第一个http请求包就是我们想要的结果,查看其query string,如下:
看起来挺简单的不是,我们得到以下几个信息:
请求url为http://weixin.sogou.com/weixin
请求类型为 Get
请求参数如上图
发现将请求参数tyepe 改成 2,就是获取关键字搜索文章的结果
比较简单
2. 模拟页面请求:
我们直接用 url, 请求参数params, 还有谷歌浏览器的 user-agent 请求,发现可以成功的获取到我们想要页面的源码,接下来我们获取搜索结果下的第一个公众号即可(这意味着需要准确的给定公众号名称,太过模糊有可能获取到与其类似的公众号结果)。
3. 分析页面:
先确定爬取思路,第一步获取微信公众号链接,再通过该微信公众号链接获取其最近十条推送的相关信息,包括标题,日期,作者,内容摘要,内容链接(事实上,我们发现有了微信推送链接之后就能很轻松的获取其推送主体内容,但不包括点赞数和阅读数,这几个数据只能在微信手机端才能查看,如果有机会的话,下次记录下自己手机微信抓包爬虫的过程)。
于是第一步我们获取公众号链接:
这里我们直接使用正则表达式提取即可(这么简单的就不用xpath,bs4了,依赖标准库和第三方库还是有所不同的。)
(抱歉被水印挡住了orz,换一张。)
第二步根据微信公众号链接获取最近十条推送信息:
(我只写了一篇orz,以后多加油。)
ctlr U 查看网页源码,发现原始信息都放在一个js变量里面。
好办,继续正则提取,将json格式的字符串转换成python里面的字典,有两种办法,第一种是用 json.loads 方法, 第二种是用内置的 eval方法,这两种方法有些区别,比如说单引号和双引号, json格式中使用的是双引号, python字典一般是单引号。
OK,获得原始推送信息数据了,但这里面有很多我们用不到的信息,将其剔除一下,值得一提的是,datetime的值是一个timestamp,我们需要将其转化为直观的时间表达。
到此,关于微信公众号的爬虫差不都就解决了,接下来需要将其封装为类。主要部分代码如下。
另外,关于关键词搜索文章的爬虫接口我也一并写了,AccountAPI,ArticleAPI,其父类是一AP类,API类有query_url, params, headers, _get_response, _get_datetime等变量和方法,供于AccountAPI,ArticleAPI共用。
代码放在 github仓库,有兴趣可以看看
放两张使用截图
结语:
这么简陋的一个爬虫称其为api,我实在是有点胆大妄为了。小打小闹而已,难登大雅之堂,需要向各位大佬虚心学习。