252012
 

原创文章,转载请注明来自Sean的技术博客

去年的十一月份,结束了在某杀毒软件公司中国研发中心为期半年的实习后回到学校。论文开题已经结束,手头事情不太多。刚好有位国内名校的教授需要做一个从Web站点抓取每小时滚动的数据,并保存成Excel表格形式的文件这样一个程序。凑巧找到了我,于是就有了这么一个项目。

整个项目从需求分析,到软件架构设计,再到编码、测试以及最后的部署,都是自己一个人独立完成。也算是一个小小的锻炼,让我知道了为何对需求的理解是如此重要,因为这是客户唯一需要的东西……因为项目还在运行之中,所有有些设计项目具体内容的部分就只能隐去了。这一篇博文和后续的几篇用来讲一下项目中碰到的一些问题和解决思路。

需求概述

从某Web站点抓取数据,每小时一次。数据分两类,一类是“区域”的小时平均值(3个);第二类是“区域”中“点”的每小时取值(3个)。区域共有约15个,每个区域包含2个到10个不等的点,每个点提供3个数值。数据最终格式应为Excel表格,表格包含上述数据在一年内的所有值。

需求分析

  1. 从数据发布网站每小时抓取xxx数据,并以合适的形式保存。发布网站使用的发布方式为网页嵌入Silverlight控件展示,控件无法以HTML的分析方式得到数据,必须进行抓包,如果数据包被加密,则还需要反编译控件以破解其加密算法,从而解密数据。幸而该网站使用的是明文传输,HTTP GET形式向数据服务器发起请求,返回UTF-8编码的明文字符串。因此,抓取的重点在于研究其GET命令的形式和返回字符串的结构。
  2. 使用WireShark抓包分析,忽略TCP连接的三次握手,由第一次HTTP GET请求开始追踪每一个TCP segment of a reassembled PDU。得到了:
    • 区域均值的GET请求字符串,及相应的返回值;
    • 每个点数据的GET请求字符串及相应的返回值;
    • 返回值的格式是UTF-8文本,组织方式为JSON,除了所需的三个值之外还有其他附加数据。
  3. 存储方式:根据上面的需求,使用数据库存储无疑是性能和伸缩性最佳的,然而与客户要求的Excel文件有出入。再考虑使用Plain Text存储,通过文件系统中的树形目录结构区分区域、点、日期、时间等,因为源数据格式就是普通文本,所以这种方式的优点是可以最大限度的保留原始信息,但是显然不利于数据的检索和使用等,只能是作为备份手段使用。第三种方法是直接按需求的格式保存为Excel文件,其优点不必多言,缺点却也非常明显,性能实在是低下。因此,本系统考虑用数据库存储信息,再通过额外的附加程序将数据库生成目标xls格式,同时通过txt进行数据的备份,以防原始信息的丢失。

经过上面的分析,就可以开始设计整个程序的架构了。在实际开发过程中,并非自顶向下的进行设计的,而是先建立了多个快速的程序原型,分步实现数据的①下载②分析③有效信息提取④存储为文本。基于这些小的程序片段最终合并为完整的程序,然后重构和优化和测试。

整个程序使用Python开发,用到了xlrd, xlwt和xlutils三个第三方库。