在我的终端中,我正在运行:
curl --user dhelm:12345 \https://stream.twitter.com/1.1/statuses/sample.json > raw-data.txt
curl的输出是直播的Twitter数据,正在写入文件raw-data.txt
在python中,
import json
posts = []
for line in open("/Users/me/raw-data.txt"):
try:
posts.append(json.loads(line))
except:
pass
我在python中读取文件并使用json解码器并将结果附加到帖子。
现在,问题是我不希望我的程序在python脚本到达文件末尾时结束。相反,当我在终端上运行的卷曲将更多帖子附加到文件raw-data.txt时,我想继续阅读。
答案 0 :(得分:1)
我不知道语言是否可以保证这一点,但我知道它在Unix上至少至少 CPython 2.x和3.3+。所以,如果您不关心3.0-3.2(或者可以自己测试),而不关心Windows(或者可以自己测试)......
当您到达EOF时,您的for line in f
循环将完成。但它不会关闭文件或任何东西;它所做的就是让文件指针停留在EOF上。如果您尝试再次循环,并且已写入更多数据,您将获得新数据。
所以,你可以这样做:
with open("/Users/me/raw-data.txt") as f:
while True:
for line in f:
try:
posts.append(json.loads(line))
except:
pass
这个问题是,当你达到EOF时,它会尽可能快地旋转,验证它仍处于EOF状态。所以你真正想做的就是阻止,直到有更多的数据。您可以在某些Unix平台上使用select
执行此操作,但不是全部。您可以使用特定于平台的文件通知API,或围绕此类API的跨平台包装器。
如果您使用的是Python 3.4+,则可以使用stdlib中的selectors
模块,它将为您提供适用于Solaris,Linux,OS X和任何其他* BSD {{3}的模块。 1}},并且在一些只有kqueue
的Unix平台上......但是在Windows上它会失败,而在某些Unix系统上它会尽可能快地旋转。如果你找不到好的选择器,你可以通过拒绝开始来解决这个问题。
或者,如果最坏的情况发生,你可以在EOF睡觉一下(可能有一些指数退避,但只能达到合理的短暂限制)。这是select
在无法检测通知的平台的端口中所做的事情。
所以:
tail -f
答案 1 :(得分:1)
我认为这是XY problem。因为您无法想到在Python中逐行传输HTTP请求的方法,所以您决定使用curl
对文件进行流式下载,然后从Python中读取该文件。因为你这样做了,你必须处理在请求仍在进行时遇到EOF的可能性,因为你已经赶上了curl
。因此,你无缘无故地让自己变得更加努力。
虽然流式下载可以使用stdlib完成,但它有点痛苦; requests
库让它变得更容易。所以,让我们使用:
import json
import requests
from requests.auth import HTTPBasicAuth
posts = []
url = 'https://stream.twitter.com/1.1/statuses/sample.json'
r = requests.get(url, auth=('dhelm', '12345'), stream=True)
for line in r.iter_lines():
try:
posts.append(json.loads(line))
except:
pass
这就是整个计划。