学习强国自动化工具源码浅析

要问现在中国最热门的app是什么,大家都知道。

强国现在已经变成了一个动词。大家都喜欢强国得快一些,方便一些。当然,有需求就有实现。

目前Github上排名前列的自动化强国工具主要有fxxk-xuexiqiangguo和Panda-Learning两款。

前者源代码js写的,并且经过压缩,可读性很差(说白了,是我不熟悉javascript)。这次就来简单分析后者的Python代码,看看计算机程序是怎么实现大业自动化的。不打算逐行分析,只挑一些比较有代表性的功能实现部分说说。

从mydriver.py中可以看到它用的是selenium——一个无头浏览器框架,在启动时载入。搞爬虫的人都知道这种支援外部浏览器(如firefox、IE、chrome等)的自动化测试工具。Panda-Learning用的就是chrome。selenium和chrome之间要通过一个驱动程序来桥接——webdriver。

装得更像真实用户

主要用随机请求头和随机滑动窗口来处理。

PandaLearning内置了各种user agent的列表,每次登录时随机选一个,让http header看起来像真人的访问请求。

至于随机滑动窗口,还是用webdriver的driver_article.go_js()函数来执行滑动的javascript代码,模拟真人手指上下滑动的行为:

1
2
3
4
5
6
for i in range(a_log, a_log + a_num):
driver_article.get_url(links[i])
time.sleep(random.randint(5, 15))
for j in range(120):
if random.random() > 0.5:
driver_article.go_js('window.scrollTo(0, document.body.scrollHeight/120*{})'.format(j))

性能提升

主要用上了多线程和headless browser。

为了提高程序性能、降低功耗,selenium在headless browser启动时,可以通过参数来选择不加载图片,关闭声音,不使用GPU,关闭沙盒。

1
2
3
4
5
6
7
8
9
10
11
if noimg:
self.options.add_argument('blink-settings=imagesEnabled=false')
if nohead:
self.options.add_argument('--headless')
self.options.add_argument('--disable-extensions')
self.options.add_argument('--disable-gpu')
self.options.add_argument('--no-sandbox')
self.options.add_argument('--mute-audio')
self.options.add_argument('--window-size=400,500')
self.options.add_argument('--window-position=800,0')
self.options.add_argument('--log-level=3')

多线程的实现用了python内置的threading模块,在threads.py里,很简单的二十几行代码,顺便实现了线程锁。

其他人性化的改进

模拟账号登录是用了钉钉的登录接口。在登陆后保存cookie。

通过WebDriverWait()函数等待界面元素加载完成,来对付网络缓慢的问题。

全平台打包发行

我们看到它居然支持win/osx/linux(rpm+deb)/rsp 。因为编程语言是Python,并没有平台相关的代码部分,移植到每个平台上也很容易。

Windows的发行版下貌似用的是pyInstaller打包,其实也可以用python 的portable版——虽然没有exe。每个发行版都内置了一个配置好webdriver的对应平台下的chromium,开箱即用。

魔高一尺,道高一丈。这种自动化工具的使用隐患很大——就技术而言,我猜可能的突破点在充当无头浏览器的chromium的某些特性上——chromium肯定和正式的chrome发行版有些不同;同时为了提升程序性能的一些作弊技巧也会成为软件弱点,比如可以反过来检测界面元素是否加载完全来判断你是否使用了真的浏览器。

你会用吗?

你说呢。