zoukankan      html  css  js  c++  java
  • 新浪微博爬取笔记(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文件中。

     

  • 相关阅读:
    电脑连不上网
    decompiler of java
    emmmmmmmmmmmmmmmmmm01
    WEB-INF
    tan?
    spring配置
    maven安装和使用前的几个点
    ※剑指offer系列29:两个链表的第一个公共结点
    剑指offer系列28:数组中的逆序对
    剑指offer系列27:第一个只出现一次的字符
  • 原文地址:https://www.cnblogs.com/manqing/p/4456724.html
Copyright © 2011-2022 走看看