0%

批处理的一个简单应用

事情是这样的,我女朋友在百度的网络推广部门,上个周五的时候集体加班,原来上面布置了一个任务。简单的说,就是输入一个url,然后截全屏(可以用PrintScreen),浏览器拉到最下面(或者end键),再截一次屏,并把再次截屏保存。据说url一共有6k个,全部人工截屏。嗯,想想就可怕。

我第一次想到的是以前在百度实习的时候用过superjs做的自动化检测或许有用,但是具体怎么做的时候也没有什么清晰的概念。昨天晚上九点的时候突然想起来这件事了,于是就去搜索了一下,但是令人失望的是没有找到。然后我想到以前在linux下面的终端操作,浏览打开页面可以用下面的终端命令。

1
firefox www.legendtkl.com

但是,百度那边用的肯定是windows,这不是黑,毕竟windows在大规模管理的时候比Linux优势还是挺大的。然后自然就想到了批处理。批处理,也就是.bat文件,简单来说,就相当于linux下面的shell,里面的内容就相当于dos命令。以前用过批处理,但也只局限于简单的启动多个应用程序,和小白没有区别。

确定了解决方案,下面就要把大问题分解成小问题。1.浏览器每次打开url,可以将url放在文本文件中,利用bat命令读出,然后调用浏览器程序。2.bat如何读取文件?3.如何实现截屏并保存?4.保存的文件名怎么设置。初步分解成4个小问题,但是我一直坚信,真正的boss在游戏开始的时候肯定是隐藏的。下面开始一步一步分析并编写代码。

第一个问题,浏览器打开url简单,很上面说的shell下是一样的。bat如何读取文件,如果我们将url逐条放置在文本文件中,那么如果逐条读取呢?第一反应:循环!然后搜索,发现for循环可以满足。如何实现截屏?这个我第一反应是模拟键盘动作。然后搜索了一下,发现了VBS,但是这这个场景下不太适用,或者说应用到这个场景下很麻烦。然后就想到了调用PrintScreen的系统API。但是就在这个过程中,偶然发现了nircmd,在它的官网上是这样描述的:“NirCmd is a small command-line utility that allows you to do some useful tasks without displaying any user interface.”就这一句,我知道这就是我需要的东西了。具体一点nircmd实现截屏通过如下命令:nircmd savescreenshot 文件路径。最后一步,保存的图片文件名问题,这个我想的很简单for循环读取的时候设置一个变量,每读一个url,变量自加1。这个时候,问题的大体思路已经确定了,但是没有考虑到END键如何实现,这个后面再说。经过简单的代码语法学习,代码的最初版本出炉了,如下。

1
2
3
4
5
6
7
8
9
set num=0
set jpg=.jpg

for /f %%i in (url.txt) do(
set /a num+=1
firefox %%i
nircmd savescreenshot %num%.jpg
)
pause

这时候,问题开始显现了。第一个最直观的感觉:循环体没有执行。这个过程中,也让我感受到了弱类型语言调起来真的很让人崩溃。通过层层排除,发现问题最后竟然是do后面不能直接加括号,得有空格!作为一种脚本语言,竟然对格式这么挑剔,而且这么少见的语法,着实让人崩溃。但是,问题并没有完:通过保存的图片来看,只有一张num=1,我首先确定自增操作符是可行的,其次代码顺序也不影响,还有blabla。要解决这个问题,需要了解批处理一个运行机制:变量延迟。批处理处理命令时是一行一行读入的,for循环包含括号,也被当作一行,所以在右小括号结束前,变量变化是不起作用,解决方案是启动“延迟变量扩展”。经过一些简单的修改,第二个版本出来了。

1
2
3
4
5
6
7
8
9
10
11
@echo off
setlocal enabledelayedexpansion
set num=0
set jpg=.jpg

for /f %%i in (url.txt) do (
set /a num+=1
firefox %%i
nircmd savescreenshot !num!.jpg
)
pause

我本来已经有点被这个问题弄的有点上头了。但是还有问题没有解决。通过观察保存的截图发现了下面的问题,如图。

网速加载慢,这个问题比较好解决,设置延迟来解决。最后还有一个问题就是END键的问题,这个我没有想到比较好的方法,最后不得已加了人工交互的过程,这个也是这个脚本最大的败笔了吧!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@echo off
setlocal enabledelayedexpansion
set num=0
set jpg=.jpg

for /f %%i in (url.txt) do (
set /a num+=1
firefox %%i
ping -n 2 127.1 >nul
nircmd savescreenshot !num!.jpg

::这5s延迟需要人手动按键END键
ping -n 5 127.1 >nul
nircmd savescreenshot !num!end.jpg
)
pause

在实际应用的时候,当url过多的时候,浏览器每打开一个标签页就会耗掉一部分的内存。所以要实时的清理,当然这个清理可以人工来做,也可以脚本来做。在代码设计的思想中,当出现两段完成一样的代码的时候,我们就应该将这段代码提出来。那么实际生活重复的工作呢?