Json.dump() 在流式传输推文时不起作用

Json.dump() not working while streaming tweets

大家早上好,
我对我的 Twitter 机器人赞不绝口 - 我需要将流式推文(到达 json)转储到一个文件中。 我以前通过将它写为 utf8 格式的字符串来完成此操作,但现在证明我仍然需要过滤一些数据,因此将其作为 json 存储在文件中似乎是最简单的方法。 我相应地编辑了代码:

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

access_token = #####
access_token_secret = ##### 
consumer_key = #####
consumer_secret =   ##### 

class StdOutListener(StreamListener):

    def on_status(self, status):
        print(status)
        today = datetime.datetime.now()
        with open('/git/twttrbots/data/Twitter_Raw %s' %
                        today.strftime("%a-%Y-%m-%d"), 'a') as f:
            json.dump(status, f)  # <- doesn't work
            #f.write(json.dumps(status))  # <- doesn't work
            #f.write("Blah")    # <- works perfectly fine

if __name__ == '__main__':
    while True:
        try:
            #login using auth
            l = StdOutListener()
            auth = OAuthHandler(consumer_key, consumer_secret)
            auth.set_access_token(access_token, access_token_secret)
            stream = Stream(auth, l)

            #filter by hashtag
            stream.filter(track=['bitcoin', 'cryptocurrency', 'wonderlandcoin',
                                    'btc', 'fintech', 'satoshi', 'blockchain',
                                        'litecoin', 'btce'])
        except:
            print("Whoops, dicsonnected at %s. Retrying"
                    % datetime.datetime.now())
            continue

文件已创建,状态肯定已读取(我的终端中有打印输出)但在某个地方,我的数据被炸毁到必杀技,而不是我的文件 - 因为它在 0 字节。

我发现了类似的情况 here 和其他平台,然而,他们使用 json.dumps() 而不是 json.dump() - 尽管我也尝试了这两个功能(使用 f.write(dumps(status))),但其中 none 似乎有效。

现在,我不是一个彻头彻尾的傻瓜;我很清楚这可能是我的问题 - 不是 JSON 错误 - 但我无法弄清楚我做错了什么。

我唯一能做的就是将它归结为我的 with open() 语句中发生的错误,让我相信它与 open() 模式有关,或者我将数据写入文件的方式。我知道这一点,因为上面链接的问题的答案在我的机器上运行良好。

当然,我可以使用 subprocess 模块并调用将打印(状态)转储到文件的管道,但这不能解决这个问题吗?

附录
根据要求,这是我的控制台 output.

Here's 我调用 logger.debug('status dump: %s', json.dumps(status)) 时记录器捕获的内容 logger.debug('status dump: %s', json.dumps(status))

我必须做的初步观察(因为当我尝试 运行 这个脚本时它变得令人沮丧):

不要让你的 except 子句太宽泛,你会捕获所有内容(包括 KeyboardInterrupt)并且很难停止执行。

这是可选的,但最好添加适当的中断:

except KeyboardInterrupt:
    exit()

你正在做的第二件事只是让你的生活变得更加艰难,你不仅是在用光秃秃的 except 捕捉一切;你没有打印相应的错误。添加这个将抓住这种情况下的罪魁祸首,为您指明正确的方向,让您的生活变得更加轻松。

except Exception as e:
    print("Error: ", e)
    print("Whoops, dicsonnected at %s. Retrying"
            % datetime.datetime.now())

这会输出一个(相当恶心)消息,它基本上打印出 Status 对象并以一行通知结束你那个对象:

is not JSON serializable

这有点合乎逻辑,因为我们在这里处理的不是 json 对象,而是从 tweepy.Stream.

返回的 Status 对象

我不知道为什么 tweepy 的创建者会这样做,我相信这背后有充分的理由,但要 解决您的问题 您可以简单地访问底层 .json 对象:

json.dump(status._json, f) 

现在,你应该可以开始了。


无法将 'bytes' 对象隐式转换为 str

这似乎是一个内部 tweepy 问题,与从 Python 2Python 3.x 的过渡有关。具体来说,在文件 streaming.py 中:

File "/home/jim/anaconda/envs/Python3/lib/python3.5/site-packages/tweepy/streaming.py", line 171, in read_line
    self._buffer += self._stream.read(self._chunk_size) <--
TypeError: Can't convert 'bytes' object to str implicitly

第一个可能的解决方案:

用户 cozostweepy GitHub 存储库上提出了一个解决方案(并且根据回复,有效)建议:

In streaming.py:

I changed line 161 to:

self._buffer += self._stream.read(read_len).decode('ascii')

171 至:

self._buffer += self._stream.read(self._chunk_size).decode('ascii')

然后重新安装。

尽管我不确定他所说的'reinstalled'是什么意思。

第二种解决方案:

tweepyPython 2.7.10 结合使用。它就像一个魅力。