iMacros脚本运行三天,爬取了40万行现代化支付行号
文章目录
离题万里的开场
码农界有个著名的“三次法则 (rule of three)”:如果一段代码重复出现了三次,就要考虑抽出来写一个子程序,以便复用。这是条宝贵的法则,可以衍生出更多的强迫症版本,随随便便就能举出很多喜闻乐见的例子:
比如
- 一个词在同一句话里出现三次就不能忍,必须换近义词;
- 一件事手动做三次就不能忍,必须写程序自动化;
- 一顿饭重复吃三口就不能忍,必须开发一个喂饭机;
- 同一处空气重复呼吸三口就不能忍,必须装一台呼吸机
……
发人深省,对不对?这些正是当今最严肃而真实的信仰,有着最为坚定的践行者。在古代2015年全球最大的雄性交友平台GitHub上出了个网红毛子码农、脚本狂魔Narkoz,他的人生信条是:如果一件事要耗费自己90秒以上,那就写个脚本。这些奇葩的脚本包括:
脚本
- 如加班到21点以后就自动给老婆发马屁短信;
- 收到蠢货DBA的任何求助邮件后自动恢复数据库的最近备份
- 让咖啡机等待17秒然后煮杯咖啡并等待24秒再灌入杯子(正好是作者起身走到咖啡机前的耗时)
- ……
从时间效益的经济学评价来讲,这个准则烂透了。这好比为了节约每天通勤的公交车钱,去买了一辆跑车。但跑车本身还是很拉风的。若能竖立起极客死宅的品牌形象,还是可能会产生某些潜在的溢价——比如说,会有更多的人请你修电脑。
判断一个人是否天生适合当码农,很重要的一点就是看他/她有没有这种懒癌强迫症。而这种强迫症的形上学本质是:对自由王国的无尽向往。——重复劳动太蠢了,它侮辱人类的尊严,阻碍我们证法悟道,必须消灭。这就是自动化的诞生。
所以——尽管技术上跌跌撞撞,也并不妨碍我隔三差五搞个三脚猫爬虫出来。这回的主题又跳跃了:爬取现代化支付行号。
这就带来了第一个问题
定义
所谓现代化支付行号 (CNAPS)
也叫联行号。
就是中国人民银行搞的一套12位银行代码,用来做自动清算的。在通过手机银行app转账时,选择收款方账户时,也会看到这个代码。它的结构如下:
|
|
所以如果要搭一个跟支付清算相关的系统,就很有必要把CNAPS作为基建纳入考虑。这套代码并不公开,但是公开渠道仍能从一些银行的官网查到。比如河北银行、浙商银行。
随手上去试了两把,还挺好用。于是思路比较清楚了:穷尽所有查询策略,把返回的结果提出来存好。
怎么爬咧?
首先,选型要精准
上面提到的这两家都要输校验码,攻起来有门槛。所以退而求其次,发现一家中原银行。
这就比较好对付一些,而且信息更多,连网点地址也提供。
其次,办法要对路
- 要理智。当然不能手工复制粘贴。平均查一个结果需要点行名、省、市,输验证码、按确认,超过10次交互动作。几千次这么做下来,非死亦残。更不要提错误率了。放弃
- 我比较熟悉的
rvest
这类简单的R爬虫包,只能对付静态网页,无法模拟网页交互行为。放弃 - Python的
scrapy
框架很牛,也能对付验证码、AJAX异步之类问题。次一点,R里面也有Rcurl
。但我都不会。放弃 - 要模拟用户交互行为最好的办法是
Selenium
这类框架(代码版按键精灵),但是当时我还不会。放弃。 - 其他。不明
所谓“夫未战而庙算者,得算多也”。经过一番严谨的分析,我发现:技术上搞不定——再次落入了经典的“看得上的买不起,买得起的看不上”窘境。
曲线救国
办法还是有的,但就是要先停下来,离题万里去讲另一个故事。
在OA领域,我们经常会把一系列小操作对应的系统指令录下来,套个循环再复用,那就是VBA宏语言。所谓宏,实质上就是定义一组模式替换规则,套用到一组命令上进行批量批处理。这不就是“录制-修改-复用”自动化党的福音吗?看看我们平时用的最多的宏,通常就是VBA,SPSS,SAS,以及各种各样的游戏作弊器。那就是宏天生的战场。
对于本地的任务,其实最合适的工具是Selenium IDE (或Katalon之类替代品),一样从录制宏开始。但我当时并不会。好在Firefox里有一个历史悠久的代替品:iMacros。看,名字里就有一个“宏”。它也有Chrome和IE的版本,通过浏览器扩展商店装好后,模样长这样:
如果自己录一段宏,打开后长这样:
由于完全是一堆动作指令,所以很容易读懂。无非是关闭其他标签页,打开一个网址,依次在几个文本控件里填入内容,最后点按钮提交。
双击录好的iim脚本运行,就把刚才的录入工作重复执行一遍。就跟自己动手一毛一样。
想象一下你有几千条记录要在网上填入。用imacros,只要在脚本同目录下准备一个csv,整理好数据,然后修改一下上面的代码,读入csv,逐行扫描,按布局顺序提取数据{{!COL1}}
、{{!COL2}}
、…,填入对应的控件,提交。接下来边喝茶边看屏幕飞滚,繁复的录入任务就自行完成了。
节外生枝的JavaScript
按说imacros已经给了很完美的循环方案:在iim脚本里给内置变量{{!LOOP}}赋一个初始值,然后在执行面板里设置一个({{!LOOP}}的)Max值,点Play Loop即可。但这只能对付单层循环。在中原银行这个案例上,单层循环是不够的。理论上需要三层循环:
|
|
大约80个银行类目,34个省份,650个城市,这样完整运行一遍要有17.7万个组合。但实际上34个省份和650个城市不会完整组合,每个省份只可能匹配其属下的那几个城市。省份选择“江苏”后,硬要让脚本到城市下拉框找“杭州”,只能逼它报错。所以省份、城市的两层循环(j, k)实际上应当合并。
饶是如此,仍有两层循环。假如硬是压成单层,就得在csv里把所有组合罗列一遍,imacros表示无力。所幸这个工具还有不错的延展性,可以执行vbs和js脚本。查询、提取、存储之类还是可以用imacros宏来完成,外面搭一个js的循环壳调用iimPlay
就行。伪代码看起来大约是这样:
|
|
心里有底了。开工。
提取银行和省份+城市的控件值
Chrome里F12,可以看到银行下拉菜单的载入值齐齐整整。
选中’banksite’这个节点,右键copy element复制下来。到R里,赋值给banks。
|
|
用R快速处理一下:
|
|
这样直接就提取成了一个文本向量。如果在Windows,可以复制outerHTML,用readClipboard
来直接读剪贴板。所以定义一个getCbId
函数,直接处理成js列表。
|
|
所以这个scrapy_cnaps.js的起头部分就变成了:
|
|
以此类推,把所有省份和城市的组合都找了出来。
|
|
构建循环
由于解析返回结果的页码需要用到正则,里面一大堆转义符,如果通过js来拼接脚本源文本,会让难度雪上加霜。所以我决定把最难的脚本单元提出来,最后拼到主脚本里。
获取返回结果的页码
点了查询之后,结果是分页显示的:
|
|
所以只要探一下下一页和末页的链接有没有绑onclick
事件,就知道是不是有效。
- 如果搜出结果,“下一页”能点,说明不止一页,那么就可以往下点开页面,直到末页。
- 如果点不了,就不用费劲循环了。
于是写了个脚本getNextLastPage.iim,用SEARCH
正则表达式的方法从页面源代码里提取js绑定。
|
|
imacros提供了一个iimGetLastExtract
的接口,能把iim脚本提取的结果以数组形式拿出来交给javascript或者vbs。
获得控件标签键
脚本交互时用到的是控件值,所以js工作脚本里只提供了100、101这类值列表。但我希望最终下载的csv以“银行_省份_城市_页码”,而不是“银行value_省份value_城市value_页码”的纯编码方式命名,所以得再写个getBankProvCity.iim,从三个下拉框控件属性标签里把“北京”、“天津”这些键取回来。
|
|
事后想想,直接在预处理时把键和值都解析出来写进js里岂不是最方便。真是智商捉急。
功能集成
写好两个工作脚本,就可以着手搭集成脚本了。
|
|
说时容易做时难。因为技术三脚猫,调试这些玩意儿花了很多时间。最坑爹的环节就是正则转义。
运行
工程搭好后,把脚本放在虚拟机上跑了三天,幸运的是网站似乎没有反爬虫策略,夜间也不关服务,于是让我顺顺利利地跑完了。
看到上千个文件静静躺在文件夹里,感觉到了巅峰愉悦。
里面的文件纷纷长这样:
R合并csv
为啥之前费尽周章地格式化命名下载结果呢?因为我需要把文件名里的信息提取出来,合并到数据集里。下面这个R脚本定义了一个parseCsvTbl
函数,就负责把csv文件名里的银行、省份、城市解析出来合并到数据集中。
|
|
跑完脚本,数据变成了:
一共40多万条记录。谢天谢地,老泪纵横。
但是!
你以为这是一篇萌蠢拙计、热情洋溢的imacros软文?那你错了。我只是为了说明一件事:
为了偷懒,我勤奋到废寝忘食。
但至于imacros,我绝不推荐。这是一段技术弯路,所有有志于自动化的,应该直接去学Python和Selenium,不要给无良付费软件一毛线的活路。
首先,今年的11月份,Firefox发布了新版Quantum,运行速度快了很多,但是API全变了。一众网红扩展纷纷蒙圈,统统跑不起来了。其中就包括了imacros。官网很快发了一则通告,大意是“用不了啦,大家赶紧降级Firefox。要不给Mozilla写个万民伞,让他们重新把废掉的那些API弄回来吧。”
开历史倒车还开出情怀来了。
随即,就在前两天,这家“全球最流行的浏览器自动化解决方案”提供者,升级了imacros浏览器插件,样子少许好看了点。然而免费版的功能却从猛犸缩水到野猪。
- 免费版最多只能录50个动作
- 免费版不再能读取本地文件
- 免费版不能回放iim脚本
- 只有IE版插件能用csv作输入源,不能超过100行、3列 …
要达到以往免费版的功能,需要升级到个人版。价钱比企业版可便宜多了,大约只需要……700大洋吧。
瞧这点出息,难怪欧洲软件企业而今越来越排不上号。市占率套现的玩法千千万,它却选择直接杀鸡取卵。这应该是我第一次,也是最后一次吹imacros。写完此文,我就把imacros彻底卸了。
工具没那么重要,重要的是理念。
Save your life. Automate everything.
[完]