批处理下载全校毕业照

从Windows 95开始,Windows操作系统正式脱离了DOS。在图形界面以外,“MS-DOS方式”和“命令提示符”仍然是Windows用户常用的工具。命令行下的批处理,则是Windows系统中最方便的编程工具。

早在Windows之前,DOS中就已经有了“批处理”这个概念,批处理文件的扩展名为bat。从Windows XP开始,command.com变成了cmd.exe,命令行解释器更是增加了大量新功能,使批处理的功能更为强大;许多外部命令(需要独立exe或com程序)变成了内部命令,使批处理的性能有所提高;批处理文件的扩展名是bat或cmd。

下面,我将介绍如何用一个批处理文件下载全校的毕业照。

考察情况

上海交通大学F05级毕业生的毕业照由上海瀚源数码科技有限公司负责拍摄。拍摄后3天,学生可以登录瀚源数码网站,查询与校对本人的图像信息。查询过程中,需要输入学号和身份证号码,两者匹配才能看到照片。

我输入了自己的学号和身份证号码,成功看到我的照片,照片的地址是http://www.spring-pic.com/Images/UpPhoto/PUTONGGAOXIAO/10248我的十位学号.jpg。清空cookie,直接输入照片地址,同样可以看到我的照片;改成其他同学的学号,也可以看到相应的照片。

因此:查询照片只需通过学号构造正确的图片地址,而无需其他验证。

准备工具

  • wget.exe,GNU标准下载工具;从GnuWin32下载wget

  • 花名册一份,自己找,用EXCEL等保存成CSV格式;我找到的花名册格式形如:

      楼栋,房间,姓名,性别,学号,班级,备注,备注,学院
      D99,999,某人姓名,男,5aabbb9ccc,Faabbbdd,,,某个学院
    

    其中学号在第5列,文件名为su.csv

提取学号

上海交通大学的学号为十位,形式为eaabbbfccc,各数位含义如下:

  • e 学生类型,5=本科,1=硕士,0=博士
  • aa 入学年份后2位
  • bbb 学院代码
  • f 入学季节,9=秋季,1=春季
  • ccc 学生编号

瀚源数码网站上只有F05毕业班学生的照片,因此提取学号要完成的任务就是:读取su.csv,取出第5列的学号,将505开头的学号输出到nu.csv文件中。

rem requires cmd /v:ON
echo off
del nu.csv
:: 跳过第1行的标题;每行以,为分隔,取出第5个符号赋给%%a变量
for /f "skip=1 delims=, tokens=5" %%a in (su.csv) do (
:: %%a(即学号)赋给b变量
set b=%%a
:: b变量的前3位赋给c变量
set c=!b:~0,3!
:: 如果c变量是505,那么将b变量添加到nu.csv
if !c!==505 echo !b! >> nu.csv
)

这里要注意的是!c!这样的写法。批处理中,!变量名!表示“延迟环境变量扩充”。%c%会在执行到for语句的一开始就被扩充(扩充成空字符串),循环体中对它赋值就不会生效;而!c!则要在执行到这一行时才被扩充(扩充成学号前3位)。

默认情况下,“延迟环境变量扩充”功能并没有启用。因此,要执行上述脚本,必须用cmd /v:ON命令启动命令提示符。

执行完上面的批处理脚本后,nu.csv每行包含一个505开头的学号。

下载毕业照

有了上面的学号列表,只需对nu.csv的每一行构造出图片地址,然后调用wget下载即可。

echo off
md output
for /f %%a in (nu.csv) do if not exist output\%%a.jpg wget http://www.spring-pic.com/Images/UpPhoto/PUTONGGAOXIAO/10248%%a.jpg -Ooutput\%%a.jpg -q
:: -q参数使wget不要输出任何信息

一个小小的遗憾:如果瀚源数码网站上没有某人的照片,output目录中仍会形成一张无法打开的图片,大小为5kb以内。目前只能手工删除小于5kb的文件。

照片可以发给我吗?

我不提供照片的分发,也不提供任何形式的名单、学号列表,请自行下载、收集。

ellendy网友提出,下载别人的照片属于“窥探个人隐私”。我认为,毕业照与身份证照片一样,不属于隐私信息。本文作为技术讨论,不传播下载的照片或用于下载照片的名单。同时,你的阳光技术频道建议各位读者,下载的照片只用于个人收藏和统计目的。


2010-06-20更新:我注意到 www.spring-pic.com 已经修正了这个漏洞,现在的照片文件名包含了随机的GUID,无法通过构造URI的方法批量下载。