作为总结:
1、这次做了一个非常糟糕的设计:
我采用了深度优先搜索,当初之所以采用这种方式,是因为我要爬的数据都在搜索树的叶节点上,这样可以在代码中少用一个队列,事实上,这是个烂到家的设计。非叶节点的页面会长时间占着内存。
一般爬虫会采用广度优先搜索,把要访问的连接保存在一个队列里面,好处:
A、访问过的页面占用的内存能被回收
B、速度更快,每个页面只解析一次。(虽然深度优先也是只解析一次,但虚拟机要帮忙维护很多小队列,以保持每个页面解析出来的链接)
C、容易实现多线程并行爬数据。只要保持对队列的同步,多个线程就可以同时爬数据。
2、对异常的态度
A、对待致命错误,要退出程序,不要吸收。
B、对待非致命异常,吸收异常,程序继续跑。
这次试验对数据的准确性和完整性要求不高,但由于之前采用了糟糕的设计,所以非常耗时,遇到异常不能停止,否则得重头开始爬数据。
3、设置连接超时timeout(s)
在s毫秒内,会不断尝试连接,知道超时
4、String类的subString()方法
发现当字符串很长时,subString会爆出异常,这跟java虚拟机对待字符串的方式有关
5、没有充分了解页面,在做页面模板时,要充分考察不同页面
另:唯一一点的优点是:
先对每类页面解析测试后,然后汇总,合在一起。