投稿    登录
欢迎来访~

微信公众号文章爬取之:微信自动化

Python 崔庆才 41169浏览 4评论

扫码或搜索:进击的Coder

发送

即可立即永久解锁本站全部文章

本文转载自:陈文管的博客-微信公众号文章爬取之:微信自动化

本文内容详细介绍微信公众号历史文章自动化浏览脚本的实现,配合服务端对公众号文章数据爬取来实现微信公众号文章数据的采集。服务端爬取实现见:微信公众号文章爬取之:服务端数据采集

背景:在团队的学习方面需要每周收集开发方面的博客文章,汇总输出每周的技术周报。周报小组成员收集的文章大多数是来自微信公众号,公众号的内容相对网页博客内容质量还是比较高的。既然数据的来源是确定的,收集汇总的流程是确定的,那么就把这个流程自动化,把人工成本降低到0。

一、方案选取

1、数据源选取

主要是爬取的数据来源选取,网上资料看的较多是爬取搜狗微信的内容,但是第三方平台(包括新榜、清博等 )的公众号文章数据更新做不到实时,而且数据也不全,还要和各种反爬措施斗智斗勇,浪费时间精力的事情划不来。最直接的方式当然是直接爬取微信公众号历史文章里面的内容。

在前期预研主要参考的资料是知乎专栏:微信公众号内容的批量采集与应用 

上面的方案是借助阿里巴巴开源的AnyProxy工具,AnyProxy作为一个中间人在微信客户端和服务器之间的交互过程中做数据截获和转发。获取到公众号文章的实际链接地址之后转发到自己的服务器进行保存,整个数据采集的自动化程度较大取决于微信客户端的自动化浏览实现。

2、自动化方案选取

如果是比较简单的安卓应用自动化操作的实现,一般直接使用AccessibilityService就行,UIAutomator也是基于AccessibilityService来实现的,但是AccessibilityService不支持WebView的操作,因为微信公众号历史文章页面是用WebView来加载的,要实现自动化必须同时支持安卓原生和WebView两个上下文环境的操作。

经过现有的几个自动化方案实现对比,最便利又具备极佳扩展性的方案就是使用Appium

  •     Appium是开源的移动端自动化测试框架;
  •     支持Native App、Hybird App、Web App;
  •     支持Android、iOS、Firefox OS;
  •     跨平台,可以在Mac,Windows以及Linux系统上;
  •     用Appium自动化测试不需要重新编译App;
  •     支持Java、python、ruby、C#、Objective C、PHP等主流语言;

更多资料参考:Android自动化测试框架

公众号文章爬取系统架构图
公众号文章爬取系统架构图

二、Appium安装配置(Mac)

Appium程序的安装,我这边不是使用brew命令安装的方式,直接从BitBucket下载Appium安装包,也可以从Github上下载。这边使用BitBucket 1.5.3版本。

Appium1.5.0之后的版本,需要在终端安装doctor,在终端输入命令:npm install -g appium-doctor,安装完毕之后,在终端输入命令:appium-doctor,查看所需的各个配置是否都已经安装配置完毕。下面是我这边在终端输出得到的结果:

上面打叉的都是没配置好的,在终端输入命令安装Carthage :brew install carthage

输入命令查看JDK安装路径:/usr/libexec/java_home -V

需要把上面的路径配置到环境变量中,ANDROID_HOME就是Android SDK的安装路径。

输入命令打开配置文件: open ~/.bash_profile,在文件中添加如下内容:

输入命令让配置立即生效:source ~/.bash_profile

更多安装配置资料可参考:Mac上搭建Appium环境过程以及遇到的问题

TIPS

在首次使用Appium时可能会出现一个错误:

在终端输入命令:

得到如下结果:

打开上面四个路径下的文件,添加当前的Appium版本参数,具体内容可参考:在Mac OS 10.12 上安装配置appium

三、具体代码实现

预研资料主要参考这篇博文:Appium 微信 webview 的自动化技术

自动化实现的原理就是通过ID或者模糊匹配找到相应的控件,之后对这个控件做点击、滑动等操作。如果要对微信WebView做自动化,必须能够获取到WebView里面的对象,如果是Android原生的控件可以通过AndroidStudio里面的Android Device Monitor来查看控件的id、类名等各种属性。

1、Android原生控件属性参数值的获取

在AndroidStudio打开Monitor工具:Tools->Android->Android Device Monitor

按照下图的步骤查看控件的ID等属性,后续在代码实现中会用到。

Android Device Monitor
Android Device Monitor

2、WebView属性参数值的获取

如果是在安卓真机上,需要打开WebView的调试模式才能读取到WebView的各个属性,在微信里面可以在任意聊天窗口输入debugx5.qq.com,这是微信x5内核调试页面,在信息模块中勾选打开TBS内核Inspector调试功能。

微信X5内核调试页面
微信X5内核调试页面

之后还要在真机上安装Chrome浏览器,如果是在虚拟机上无需做此操作。

接下来在Chrome浏览器中输入:chrome://inspect ,我这边使用的是虚拟机,真机上也一样,进入到公众号历史文章页面,这边就会显示相应可检视的WebView页面,点击inspect,进入到Developer Tools页面。

chrome inspect页面
chrome inspect页面

如果进入到Developer Tools页面显示一片空白,是因为chrome inspect需要加载 https://chrome-devtools-frontend.appspot.com 上的资源,所以需要翻墙,把appstop.com 加入翻墙代理白名单,或者直接全局应用翻墙VPN,具体可参考:使用chrome remote debug时打开inspect时出现一片空白

下面是美团技术团队历史文章列表的详细结构信息,具体的文章列表项在weui-panel->weui-panel__bd appmsg_history_container->js_profile_history_container->weui_msg_card_list路径下。

Chrome inspect查看WebView详细内容
Chrome inspect查看WebView详细内容

继续展开节点查看文章详细结构信息,这边可以看到每篇文章的ID都是以“WXAPPMSG100″开头的,类名都是“weui_media_box”开头,一开始的实现是通过模糊匹配ID来查找历史文章列表项数据,但在测试过程中出现来一个异常,后来发现,如果是纯文本类型的文章,也就是只有一段话的文章,它是没有ID的,所以不能通过ID来模糊匹配。

公众号历史文章列表项详细结构
公众号历史文章列表项详细结构

之后就把现有的四种公众号文章类型都找来出来,找它们的共性,虽然ID不一定有,但是class类型值一定有,四种类型值如下,这样就可以通过class类型值来匹配查找数据了。

3、具体代码实现

整体自动化是按照如下顺序:通讯录页面->点击公众号进入公众号列表页面->公众号列表项选择一个点击->公众号页面->公众号消息页面->点击“全部消息”进入公众号历史文章页面->根据设置的时间类型(一周之内、一个月之内、一年之内或者全部)逐个点击历史文章列表项,完毕之后返回公众号列表页面,继续下一个公众号浏览的操作;

1)初始化

如果是虚拟机则platformName使用具体的虚拟机名称,如果是真机使用“Android”,platformVersion和deviceName可以使用工程安装APK之后查看详细信息,对应的参数就是显示的系统版本和设备名称。

设备信息
设备信息

URL参数是在Appium里面设置的,确保”http://127.0.0.1:4723/wd/hub”字符串中的服务器地址和端口与Appium设置一致。

Appium URL参数设置
Appium URL参数设置
2)列表滑动和元素获取

不管是WebView还是Android原生ListView的滑动都需要在Android原生上下文环境下操作driver.context(“NATIVE_APP”); 滑动操作都可以通过如下代码实现,通过滑动前后的PageSource对比可以知道列表是否已经滑动到底部。

TIPS:

如果是Android原生的ListView读取到的数据是在屏幕上显示的数据,超过屏幕的数据是获取不到的,如果是WebView的列表获取的数据是所有已加载的数据,不管是否在屏幕显示范围内。

获取公众号列表数据逻辑代码如下,”com.tencent.mm:id/a0y”是具体的公众号名称TextView的ID。

获取历史文章列表数据逻辑代码如下,div是节点,上面说到公众号四种类型的文章都是以’weui_media_box’类名开头的,通过模糊匹配class类名以’weui_media_box’开始的元素来过滤出所有的公众号文章列表项。

3)元素定位方式

如果一定需要模糊匹配就使用By.xpath()的方式,因为Android APK应用如果有增加或减少了布局字符串资源或者控件,编译之后生成的ID可能会不一样,这边说的ID是指通过Android Device Monitor查看的布局ID,不是实际的布局代码控件id,布局控件id除非命名改动,否则不会变化。所以不同版本的微信客户端生成的ID很可能会不一样,如果要批量实现自动化最好使用模糊匹配的方式,但By.xpath()方式查找定位元素是遍历页面的所有元素,会比较耗时,也容易出现异常。

在测试过程中执行

时候经常出现如下错误,改为

异常消失,猜测原因就是因为By.xpath()方法查找比较耗时导致。

如果容易出现如下异常,则是因为页面的内容还未加载完毕,可以通过

方法设置下超时等待时间,等待页面内容加载完毕,具体超时时间可自己调试看看设置一个合适的值。

更多元素定位方法可参考官网:

4)chromedriver相关问题

在2017年6月微信热更新升级了X5内核之后,真机上切换到WebView上下文环境就出问题了,具体见这篇博文的评论Appium 微信 webview 的自动化技术 和 Appium 微信小程序,driver.context (“WEBVIEW_com.tencent.mm:tools”) 切换 webview 报错 看评论是通过降低chromedriver版本的方式来避免异常,但是在试过降低版本到20之后还是不行,更新到最新的版本也不行,于是放弃在真机上实现自动化,在模拟器中跑起来的速度也还可以接受。

在真机上跑的时候,切换到WebView上下文环境,程序控制台输出no such session异常,异常信息如下:

在Appium端输出的异常信息如下:

如果要替换chromedriver的版本,可以从Appium上输出的Log信息找到chromedriver的路径,在终端依次执行如下命令打开chromedriver所在的文件夹。

相应的chromedriver和Chrome版本对应信息和下载地址可以参考:

selenium之 chromedriver与chrome版本映射表

5)程序使用的JAR包

自动化脚本程序要跑起来需要两个压缩包,java-client-3.1.0.jar 和 selenium-server-standalone-2.44.0.jar ,试过使用这两个JAR包的最新版本,会有一些奇奇怪怪的问题,这两个版本的JAR包够用了。

java-client-3.1.0.jar 可以从Appium官网下载:

selenium-server-standalone-2.44.0.jar 可以从selenium官网下载:

6)虚拟机

我这边使用的是网易MuMu虚拟机,基于Android 4.4.4平台,在我自己的Mac上跑着没问题,同一个版本安装到公司的Mac上就跑不起来,一打开就崩。后面虚拟机自动升级到了Android6.0.1,脚本跑了就有异常,而且每次打开的时候经常卡死在加载页面,system so库报异常。所以最好还是基于Android4.X的版本上运行脚本,Mac上没有一个通用稳定的虚拟机,自己下几个看看是否能用,个人测试各类型的虚拟机结果如下:

1)网易MuMu:在Mac上还是比较好用的,但是最新的版本是6.0.1,初始化经常卡死,无法回退到4.4.4平台版本,脚本在Android6.0平台上切换到WebView的上下文环境异常,升级ChromeDriver版本和Appium版本也无法解决此问题。

2)GenyMotion:微信安装之后无法打开,一直闪退,页面滑动在Mac上巨难操作。

3)天天模拟器:下载的DMG安装文件根本无法打开。

4)夜神模拟器:还是比较好用的,但是Appium adb无法连上虚拟机,从Log来看一直在重启adb, 最后程序中断。

5)逍遥安卓:没有Mac版本。

6)BlueStack:无法安装,安装过程中异常退出,多次重试还是一样。

综上,如果是在Mac上运行虚拟机,目前测试有效的是网易MuMu 基于Android 4.4.4 平台的版本,其他版本和虚拟机都有各种问题。

另:附上Android WebView 历史版本下载地址(需要翻墙):

WebView 和对应的ChromeDriver版本见Appium GitHub chromedriver说明文档:

7)编译IDE

不做Android开发的可以下载Eclipse IDE,在Eclipse下运行Java程序还比较方便,拷贝工程源码中的三份文件即可

Eclipse IDE下载地址:

Java版本和对应的Eclipse IDE版本参考:

8)GitHub工程源码

源码GitHub地址:

运行Android工程查看设备信息的时候Edit Configurations切换到app,运行自动化脚本的时候切换到AppiumAutoScan。支持按最近一周,一个月,一年或爬取所有历史文章,checkTimeLimit()传入不同限制时间类型的参数即可。

四、参考资料

Appium 官方文档:http://appium.io/docs/cn/about-appium/intro/

Appium 常用API

Appium自动化测试–使用Chrome调试模式获取App混合应用H5界面元素

Appium 微信 webview 的自动化技术

Appium Girls 学习手册

Appium:轻松玩转app+webview混合应用自动化测试

Appium 微信小程序,driver.context (“WEBVIEW_com.tencent.mm:tools”) 切换 webview 报错

Appium 事件监听

妙用AccessibilityService黑科技实现微信自动加好友拉人进群聊

Appium自动化测试Android

Windows下部署Appium教程(Android App自动化测试框架搭建)

微信、手Q、Qzone之x5内核inspect调试解决方案

selenium之 chromedriver与chrome版本映射表

(Android开发自测)在Mac OS 10.12 上安装配置appium

辅助功能 AccessibilityService笔记

转载请注明:静觅 » 微信公众号文章爬取之:微信自动化

更多文章、联系博主、技术交流、商务合作

扫码或搜索:进击的Coder

进击的Coder

微信公众号 扫一扫关注

喜欢 (14)or分享 (0)

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请狠狠点击下面的

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
(4)个小伙伴在吐槽
  1. 你这种方法爬第一页的三篇文章还行,想查看更多公众号文章就不行了,anyproxy过不了微信的ssl认证的。
    刚刚好2019-07-18 13:10 回复
  2. 这种中间人挟持的方法不太好用了吧,大厂的app会有自己的一套证书验证方法,即使安了ca证书也不好使,反编译也不太能走通,学艺不精求大神指教
    dehua2019-07-08 15:38 回复
  3. 实现起来还是挺麻烦的,存下来慢慢学习下
    心灵博客2019-07-05 15:06 回复
  4. 学习了!
    samon2019-07-03 00:37 回复