【问题标题】:Json.dump() not working while streaming tweetsJson.dump() 在流式传输推文时不起作用
【发布时间】:2015-10-06 09:23:21
【问题描述】:

大家早上好,
我对我的 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))),但它们似乎都不起作用.

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

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

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

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

Here's 当我调用logger.debug('status dump: %s', json.dumps(status)) 时,记录器捕获了什么。

【问题讨论】:

  • 你能记录下未编码的文本是什么样子的吗?其中的某些内容可能会使 JSON 格式无效。
  • 我将我的打印输出添加为 pastebin 链接 - 我之前没有在我的代码中添加任何日志记录,但我会尽快实现它。
  • 添加了我的日志文件所说的内容。我第一次使用这个 si,我不确定这是记录它的正确方法。如果您有任何指示,我正在听:/
  • 这里有很多信息需要解析,但我马上注意到json.dump 会抛出单引号而不是双引号和False 不在引号中的错误。 This site 有助于测试 JSON 数据的有效性。
  • 从流中出来的有效数据肯定是 JSON - 我在使用 CLI 之前将其转储到文件中;然后我使用 JSON 模块提取数据(按行和 json.loads(line) 读取),可能只是 print() 搞砸了?因此我怀疑它与写入模式有关。 edit:把 print() 乱七八糟的刮一下;因为通过 '>' 在 CLI 中转储需要 print() 的输出,所以不可能。

标签: json python-3.x tweepy


【解决方案1】:

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

不要让你的 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

这似乎是与从Python 2 转换到Python 3.x 相关的内部tweepy 问题。具体来说,在文件 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 存储库上提出了一个解决方案(并且根据回复,正在运行),建议:

streaming.py

我将161 改为:

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

然后将171 转至:

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

然后重新安装。

尽管我不确定他所说的“重新安装”是什么意思。

第二种解决方案:

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

【讨论】:

  • 感谢指点!我没有通过json.dump(status._json, f) 倾销,但现在的错误是:Error: 'str' does not support the buffer interface。 ://
  • 我确实找到了一个有用的指针here。它仍然不是 100% 我想要转储的数据,但它确实会转储数据,所以我认为我的问题得到了回答。谢谢!
  • 我正在调查错误,如果我发现有用的东西,我会相应地更新我的答案:-)
  • 我编辑了我的答案以包括两个替代的可能解决方案。看看他们,如果你有精力,给他们一个机会。
  • 我知道解决方案一,实际上已经这样做了;为我节省了大量烦人的编码错误。但可惜,那不可能。关于解决方案 2:Python 2 是魔鬼。只是在开玩笑。我会试一试,尽管我们尽量不在 2.7 中编写代码,除非绝对没有其他方法。但我想我已经很接近那一点了。感谢您的更新!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-24
  • 1970-01-01
  • 1970-01-01
  • 2021-07-17
  • 2015-08-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多