2014-06-11 189 views
2

我正在使用Tweepy传输推文,并且希望将它们记录为CSV格式,以便我可以随时播放它们或稍后将它们加载到数据库中。 请记住,我是一个noob,但我知道有多种方式来处理这个问题(建议非常受欢迎)。在Python中将多个JSON写入CSV - 将字典转换为CSV

长话短说,我需要将多个Python字典转换并追加到一个CSV文件中。 我已经做了我的研究(How do I write a Python dictionary to a csv file?),并尝试用DictWriter和writer方法做这件事。

然而,有需要完成一些事情:

1)写键头只有一次。

2)当新的tweet被流式传输时,需要附加值而不覆盖以前的行。

3)如果值缺失记录NULL。

4)跳过/修复ascii编解码器错误。

这里是我想与落得什么样的格式(每个价值就在于单个电池):

Header1_Key_1 Header2_Key_2 Header3_Key_3 ...

Row1_Value_1 Row1_Value_2 Row1_Value_3 ...

Row2_Value_1 Row2_Value_2 Row2_Value_3 ...

Row3_Value_1 Row3_Value_2 Row3_Value_3 ...

滚装w4_Value_1 Row4_Value_2 Row4_Value_3 ...

这里是我的代码:

from tweepy.streaming import StreamListener 
from tweepy import OAuthHandler 
from tweepy import Stream 
import csv 
import json 

consumer_key="XXXX" 
consumer_secret="XXXX" 
access_token="XXXX" 
access_token_secret="XXXX" 

class StdOutListener(StreamListener): 

    def on_data(self, data): 
     json_data = json.loads(data) 

     data_header = json_data.keys() 
     data_row = json_data.values() 

     try: 
      with open('csv_tweet3.csv', 'wb') as f: 
       w = csv.DictWriter(f, data_header) 
       w.writeheader(data_header) 
       w.writerow(json_data) 
     except BaseException, e: 
      print 'Something is wrong', str(e) 

     return True 

    def on_error(self, status): 
     print status 

if __name__ == '__main__': 
    l = StdOutListener() 
    auth = OAuthHandler(consumer_key, consumer_secret) 
    auth.set_access_token(access_token, access_token_secret) 

    stream = Stream(auth, l) 
    stream.filter(track=['world cup']) 

预先感谢您!

+0

你是说你有什么不工作?另外,你总是可以将json转储到一个文件中,每行一个条目... – monkut

+0

这不起作用。是的,你可以,但我想获得csv格式。 – verkter

+1

当你说它'不工作',有什么具体的,似乎并没有工作。例如,是否有例外? – monkut

回答

1

我用facebook的图形API(facepy模块)做了类似的事情!

from tweepy.streaming import StreamListener 
from tweepy import OAuthHandler 
from tweepy import Stream 
import csv 
import json 

consumer_key="XXXX" 
consumer_secret="XXXX" 
access_token="XXXX" 
access_token_secret="XXXX" 

class StdOutListener(StreamListener): 
    _headers = None 
    def __init__(self,headers,*args,**keys): 
     StreamListener.__init__(self,*args,**keys) 
     self._headers = headers 

    def on_data(self, data): 
     json_data = json.loads(data) 

     #data_header = json_data.keys() 
     #data_row = json_data.values() 

     try: 
      with open('csv_tweet3.csv', 'ab') as f: # a for append 
       w = csv.writer(f) 
       # write! 
       w.writerow(self._valToStr(json_data[header]) 
          if header in json_data else '' 
          for header in self._headers) 
     except Exception, e: 
      print 'Something is wrong', str(e) 

     return True 

    @static_method 
    def _valToStr(o): 
     # json returns a set number of datatypes - parse dependingly 
     # https://docs.python.org/2/library/json.html#encoders-and-decoders 
     if type(o)==unicode: return self._removeNonASCII(o) 
     elif type(o)==bool: return str(o) 
     elif type(o)==None: return '' 
     elif ... 
     ... 

    def _removeNonASCII(s): 
     return ''.join(i if ord(i)<128 else '' for i in s) 

    def on_error(self, status): 
     print status 

if __name__ == '__main__': 
    headers = ['look','at','twitter','api', 
       'to','find','all','possible', 
       'keys'] 

    # initialize csv file with header info 
    with open('csv_tweet3.csv', 'wb') as f: 
     w = csv.writer(headers) 

    l = StdOutListener(headers) 
    auth = OAuthHandler(consumer_key, consumer_secret) 
    auth.set_access_token(access_token, access_token_secret) 

    stream = Stream(auth, l) 
    stream.filter(track=['world cup']) 

这不是复制粘贴&准备好了,但它是不够清楚的地方,你应该能够完成它。
对于性能,您可能希望查看打开文件,写入多个记录,然后关闭文件。这样你不会一直打开,初始化csv编写器,追加,然后关闭文件。我对tweepy API并不熟悉,所以我不确定这将如何工作 - 但值得深入研究。

如果遇到任何麻烦,我会很乐意帮助 - 享受!