新浪微博爬取笔记(4):数据清理

数据清理的部分很多,其实爬数据的过程中步骤的间隔也要做数据清理,都是很琐碎繁杂的工作。总结经验的话,就是:

1、一定要用数据库存储数据  

(我因为还不太会数据库,为了“节省学习时间”,所有数据项都用txt存储,直到最后出现了多个种类之间查找,文件夹树变得比较复杂,才觉得当初即使使用MySQL也会提高效率)

2、处理异常的语句不嫌多

3、处理数据的脚本最好打包成函数,尽量减少运行前需要改源码的机会,变量从外部传递

4、工作流程要整体写出来画成图方便查找,步骤和文件多了会有点混乱


以处理时间为例:

我这次需要得到用户的latency, 也就是从微博发出到该用户转发的时间间隔。

一条微博的信息line在txt中是这样的:

M_CdHsYyHZd 转发[313] 04月17日 16:27 来自微博 weibo.com 

一条转发:

/yunxiang  2014-09-28 12:46:07 来自火星Android /n/%E5%8D%9A%E7%89%A9%E6%9D%82%E5%BF%97 

用python处理这样一条line, 基本需要的函数就是 .split() 以及各种列表操作;

 

以处理时间部分为例。python中用来处理时间的模块主要是datetime和time, datetime比较好用, time用来得到文件信息,比如创建、修改时间之类。

时间部分有不同的格式,比如:

今天 15:00

2014-12-04 20:49:48

31分钟前

04月17日 22:00

这样就要写不同的匹配方案:

 1      if len(re.compile('\d+-\d+-\d+').findall(time_area[0])) == 1: #2014-12-04 20:49:48
 2             [year, month, day] = [i for i in re.compile('\d+').findall(time_area[0])]
 3             [hour, minute, sec] = [i for i in re.compile('\d+').findall(time_area[1])[0:3]]
 4             t = [year, month, day] + [hour, minute, sec]
 5             t = [int(i) for i in t]
 6             resultTime = datetime.datetime(*t)
 7         elif len([int(i) for i in re.compile('\d+').findall(time_area[0])]) == 1:  # 31 minutes ago
 8             postTime = file_time - datetime.timedelta(minutes = int(re.compile('\d+').findall(time_area[0])[0]))
 9             resultTime = postTime
10         elif len([int(i) for i in re.compile('\d+').findall(time_area[0])]) == 2: #04 17 22:00
11             [year, month, day] = [file_time.year, re.compile('\d+').findall(time_area[0])[0], re.compile('\d+').findall(time_area[0])[1]]
12             [hour, minute, sec] = [re.compile('\d+').findall(time_area[1])[0], re.compile('\d+').findall(time_area[1])[1], 30]
13             t = [year, month, day] + [hour, minute, sec]
14             t = [int(i) for i in t]
15             resultTime = datetime.datetime(*t)
16         elif len(re.compile('\d+').findall(time_area[0])) == 0:#today 15:00
17             [year, month, day] = [file_time.year, file_time.month, file_time.day]
18             [hour, minute, sec] = [re.compile('\d+').findall(time_area[1])[0], re.compile('\d+').findall(time_area[1])[1], 30]
19             t = [year, month, day] + [hour, minute, sec]
20             t = [int(i) for i in t]
21             resultTime = datetime.datetime(*t)
22         else:
23             print "unexpected time type, check plz"
24             sys.exit(0)

需要注意很多细节部分,比如 len() 可以对列表求长度,也可以求字符串长度; re.compile() 匹配结果返回的是字符串;等等。

 

 


 

每一次运行完后生成的数据结构可以用pickle存储,在我的例子中所存储的是字典dict。用法是这样的:

1 import pickle
2 
3 try:
4     with open('foreDic.pickle', 'rb') as f:
5         result = pickle.load(f)
6 except:
7     result = {}

这是在最开始时导入上次存储的数据结构。 pickle.load() 如果遇到了空文件会报错,因此处理这个异常,如果文件为空或是找不到文件,就新建一个空字典。

1 with open('foreDic.pickle', 'wb') as f:
2   pickle.dump(result, f)

最后将result字典存储到pickle文件中。

 

 

posted @ 2015-04-25 21:15  gooey  阅读(728)  评论(1编辑  收藏  举报