迷幻主义搬砖号子:代码复用的三次法则与当今信仰的思考

2024-09-22
来源:网络整理

↑ 点击上方蓝字“迷幻搬砖账号”关注,即刻获得以下福利(排名不分先后):

本订阅号清爽安静,不会打扰别人,长期不推送新文章。

收到推送通知后永远不能打开,增加你对红点的抵抗力;

长期服用少量毒鸡汤,可使人心脏强健,对所有毒素有免疫力;

零压力学习新知识——无需测试,无需考试,而且您可以随时忘记它。

离题的开场

程序员界有一条著名的“三法则”:如果一段代码出现了三次,你应该考虑将其提取出来并编写一个子程序以供重复使用。这是一条很有价值的规则,可以衍生出更强迫性的版本。可以很容易地引用许多流行的例子,例如:

…

发人深省吧?这些是今天最严肃、最真实的信仰,有着最坚定的践行者。古往今来,2015年,全球最大的男性交友平台上有一位著名的程序员、脚本狂热分子,他的人生原则是:如果某件事需要超过90秒,就写一个脚本。这些奇葩的脚本包括:加班到21点后自动给老婆发奉承短信、收到任何愚蠢DBA的求助邮件后自动恢复数据库最新备份、让咖啡机等17秒泡一杯咖啡,再等24秒再倒进杯中(刚好是作者起身走到咖啡机前的时间)……

从经济评估时间效率的角度看,这个原则很糟糕。这就像为了节省每天上下班的公交车费而买一辆跑车。但跑车本身还是很酷的。如果你能树立一个宅男的品牌形象,可能还是会有一些潜在的溢价——比如,会有更多的人请你修电脑。

判断一个人是否天生就是程序员,关键看他/她是否有这种懒惰的强迫症,这种强迫症的形而上本质是:对自由王国的无尽向往。——重复劳动太愚蠢了,它侮辱了人的尊严,阻碍了我们领悟真理,必须消灭它,这就是自动化的诞生。

所以,尽管我的技术很困难,但这不妨碍我时不时地制作一个爬虫。这次话题又跳了起来:爬取现代支付银行号码。

这引出了我们第一个问题

这是什么?

所谓现代支付线号()

也称为银行间号码。

这是中国人民银行为自动清算而创建的一组 12 位银行代码。通过手机银行应用程序转账时,选择收款账户时也会看到此代码。其结构如下:

1

2

** *    ****    ****           *

行别码  地区码  分支机构序号   校验码

所以如果要搭建支付清算相关的系统,就要把它当做基础设施来考虑,这个代码不公开,不过在一些银行的官网还是能找到的,比如河北银行、浙商银行等。

我尝试了两次,效果还不错。于是思路就清晰了:穷尽所有查询策略,并保存返回的结果。

怎麼攀爬?

一、选材要准确

上面提到的两家银行都需要验证码,很难破解。所以我退而求其次,找到了中原银行。

这更容易处理,并提供更多信息,甚至分支机构的地址。

其次,方法要正确

俗话说,“战前计划,必先算计”。经过严谨的分析,我发现技术上做不到——再次陷入“喜欢的我买不起,买得起的我不喜欢”的经典困境。

绕道救国

有一种方法,但它需要你停下来并偏离主题去讲述另一个故事。

在OA领域,我们经常会把一系列小操作对应的系统指令记录下来,放到循环里重复使用,那就是VBA宏语言。所谓宏,本质上就是定义一套模式替换规则,应用到一组命令上进行批处理。这难道不是“记录-修改-重复使用”自动化党的福音吗?看看我们最常使用的宏,一般是VBA、SPSS、SAS,还有各种游戏秘籍。那才是宏的天然战场。

对于本地任务,最合适的工具其实是 IDE(或者它的替代品),从录制宏开始。但我当时不知道怎么做。幸好,有一个长期存在的替代方案:。你看,名字里有一个“宏”。它还有一个适用于 IE 的版本。通过浏览器扩展商店安装后,它看起来像这样:

如果你自己录制了一个宏,打开后它将如下所示:

由于只是一堆动作指令,所以很容易理解,无非就是关闭其他标签页,打开一个网站,依次在几个文本控件中填写内容,最后点击按钮提交即可。

双击录制好的iim脚本运行,之前的输入工作就会重复一遍,跟自己动手操作一模一样。

想象一下,你有几千条记录需要在线填写。使用时,只需要在与脚本相同的目录中准备一个 csv,整理好数据,然后修改上述代码,读取 csv,逐行扫描,按布局顺序提取数据 {{!COL1}}, {{!COL2}}, ...,填写相应的控件,然后提交。然后,一边喝茶一边看着屏幕滚动,复杂的输入任务就会自动完成。

无关

据说已经给出了完美的循环解决方案:在iim脚本中给内置变量{{!LOOP}}赋初值,然后在执行面板中设置一个Max值({{!LOOP}}),点击播放循环即可。但这只能处理单层循环,对于中原银行来说,单层循环是不够的,理论上需要三层循环:

对于所有银行名称中的 i:

对于所有省份的 j:

对于所有城市中的 k:

询问

提取结果表

保存到文件

下一个 k

下一个

接下来我

银行类别大概有80个,34个省份,650个城市,跑完整个程序需要17.7万个组合。但实际上34个省份和650个城市是无法完全合并的,每个省份只能匹配其下属的城市。选择“江苏”作为省份后,强制脚本在城市下拉框中查找“杭州”只会报错。因此,省份和城市的两层循环(j,k)其实应该合并。

即使如此,还是有两层循环,如果强行改成单层,就得把所有的组合都列在csv里,无能为力。好在这款工具扩展性不错,可以执行vbs、js脚本,查询、提取、存储等还是可以用宏完成,外面还可以建一个js循环调用,伪代码如下:

for (var i=0; i <银行号码; i++){

for (var j=0; j < 省市数量; j++){

(宏,选择银行、省份、城市,查询结果)

(另一个宏返回查询结果的页码,以便可以取消选择页面)

(另一个宏提取银行、省份和城市的标签名称。

用于命名文件)

(最后一个宏循环遍历查询结果页面。

将每页结果保存为 csv)

我心里有个清晰的想法。我们开始工作吧。

提取银行及省份+城市的控制值

按下F12,就可以看到bank下拉菜单里的数值被整齐地加载了。

选择节点 '',右键复制,在 R 中赋值给 。

==请选择银行==

中原银行

中国工商银行

中国农业银行

中国银行

中国建设银行

国家开发银行

....

R 中的简要概述:

“))

((,(五)

gsub("^\\D+$", "\\1", v)), = ",")

这会直接将其提取到文本向量中。如果存在,您可以复制它并使用它直接读取剪贴板。因此定义一个函数将其直接处理成 js 列表。

()

# 按 F12 从 ZYB 页面复制 XML

如果(is.na()){

(如.(a))

}别的{

a=(as.(c(

rep.int(,(a)),a)),ncol = 2)

(一个)

所以这个.js的开头变成:

var = [100,102,103,104,105,201,202,203,301,302,303,304,305,306,

307,308,309,310,313,314,315,316,317,318,319,401,402,403,501,502,503,

504,505,506,507,509,510,512,531,532,533,561,562,563,564,565,591,593,

594,595,596,597,621,622,623,631,641,651,652,661,662,671,672,691,692,

693,695,711,712,713,714,715,716,732,741,742,751,752,761,771,775,776,

781,782,783,785,787];

var = .;

依此类推,找到所有省份和城市的组合。

变量 =[

[11,1000],

[12,1100],

[13,1210],[13,1240],[13,1260],[13,1270],[13,1310],[13,1340],[13,1380],

[13,1410],[13,1430],[13,1460],[13,1480],

[14,1610],[14,1620],[14,1630],[14,1640],[14,1680],[14,1690],[14,1710],

[14,1730],[14,1750],[14,1770],[14,1810],

[15,1910],[15,1920],[15,1930],[15,1940],[15,1960],[15,1980],[15,1990],

[15,2010],[15,2030],[15,2050],[15,2070],[15,2080],

[21,2210],[21,2220],[21,2230],[21,2240],[21,2250],[21,2260],[21,2270],

[21,2280],[21,2290],[21,2310],[21,2320],[21,2330],[21,2340],

[22,2410],[22,2420],[22,2430],[22,2440],[22,2450],[22,2460],[22,2470],

[22,2490],[22,2520],

[23,2610],[23,2640],[23,2650],[23,2660],[23,2670],[23,2680],[23,2690],

[23,2710],[23,2720],[23,2740],[23,2760],[23,2780],[23,2790],

[31,2900],

[32,3010],[32,3020],[32,3030],[32,3040],[32,3050],[32,3060],[32,3070],

[32,3080],[32,3090],[32,3110],[32,3120],[32,3140],

[33,3310],[33,3320],[33,3330],[33,3350],[33,3360],[33,3370],[33,3380],

[33,3410],[33,3420],[33,3430],[33,3450],

[34,3610],[34,3620],[34,3630],[34,3640],[34,3650],[34,3660],[34,3670],

[34,3680],[34,3710],[34,3720],[34,3740],[34,3750],[34,3760],[34,3790],

[35,3910],[35,3930],[35,3940],[35,3950],[35,3960],[35,3970],[35,3990],

[35,4010],[35,4030],[35,4050],

[36,4210],[36,4220],[36,4230],[36,4240],[36,4260],[36,4270],[36,4280],

[36,4310],[36,4330],[36,4350],[36,4370],

[37,4510],[37,4520],[37,4530],[37,4540],[37,4550],[37,4560],[37,4580],

[37,4610],[37,4630],[37,4650],[37,4660],[37,4680],[37,4710],[37,4730],

[37,4750],

[41,4910],[41,4920],[41,4930],[41,4950],[41,4960],[41,4970],[41,4980],

[41,5010],[41,5020],[41,5030],[41,5040],[41,5050],[41,5060],[41,5080],

[41,5110],[41,5130],[41,5150],

[42,5210],[42,5220],[42,5230],[42,5260],[42,5280],[42,5310],[42,5320],

[42,5330],[42,5350],[42,5360],[42,5370],[42,5410],

[43,5510],[43,5520],[43,5530],[43,5540],[43,5550],[43,5570],[43,5580],

[43,5590],[43,5610],[43,5620],[43,5630],[43,5650],[43,5670],[43,5690],

[44,5810],[44,5820],[44,5840],[44,5850],[44,5860],[44,5880],[44,5890],

[44,5910],[44,5920],[44,5930],[44,5950],[44,5960],[44,5970],[44,5980],

[44,5990],[44,6010],[44,6020],[44,6030],

[45,6110],[45,6140],[45,6170],[45,6210],[45,6230],[45,6240],[45,6330],

[46,6410],[46,6420],

[50,6530],

[51,6510],[51,6550],[51,6560],[51,6570],[51,6580],[51,6590],[51,6610],

[51,6620],[51,6630],[51,6650],[51,6670],[51,6690],[51,6710],[51,6730],

[51,6750],[51,6770],[51,6790],[51,6810],[51,6840],[51,6870],

[52,7010],[52,7020],[52,7030],[52,7050],[52,7070],[52,7090],[52,7110],

[52,7130],[52,7150],

[53,7310],[53,7340],[53,7360],[53,7380],[53,7410],[53,7430],[53,7450],

[53,7470],[53,7490],[53,7510],[53,7530],[53,7540],[53,7550],[53,7560],

[53,7570],[53,7580],

[54,7700],[54,7720],[54,7730],[54,7740],[54,7750],[54,7760],[54,7770],

[54,7790],[54,7810],[54,7830],

[61,7800],[61,7910],[61,7920],[61,7930],[61,7950],[61,7970],[61,7990],

[61,8010],[61,8030],[61,8040],[61,8060],

[62,8210],[62,8220],[62,8230],[62,8240],[62,8250],[62,8260],[62,8270],

[62,8280],[62,8290],[62,8310],[62,8330],[62,8340],[62,8360],[62,8380],

[63,8510],[63,8520],[63,8540],[63,8550],[63,8560],[63,8570],[63,8580],

[63,8590],

[64,8710],[64,8720],

[65,8810],[65,8820],[65,8830],[65,8840],[65,8850],[65,8870],[65,8880],

[65,8910],[65,8930],[65,8940],[65,8960],[65,8980],[65,9010],[65,9020]]

var = .;

构建循环

由于解析返回结果的页码需要用到正则表达式,而正则表达式中含有大量的转义字符,如果再通过js来拼接脚本源文本,难度就更大了。所以我决定把最难的脚本单元拿出来,最后放到主脚本中。

获取返回结果的页码

点击查询后,结果分页显示:

分享