如何在Clojure中保存来自twitter api的流式推文?
我已经使用clojure一段时间了,但是我不熟悉TwitterAPI()所基于的异步io 我想收集所有匹配给定关键字集的推文。例如,所有与“玛丽·罗斯”(Mary rose,英国现在流行的东西)相匹配的东西。用于流式通话的文档说,可以执行以下操作:如何在Clojure中保存来自twitter api的流式推文?,clojure,twitter,Clojure,Twitter,我已经使用clojure一段时间了,但是我不熟悉TwitterAPI()所基于的异步io 我想收集所有匹配给定关键字集的推文。例如,所有与“玛丽·罗斯”(Mary rose,英国现在流行的东西)相匹配的东西。用于流式通话的文档说,可以执行以下操作: (ns mynamespace (:use [twitter.oauth] [twitter.callbacks] [twitter.callbacks.handlers] [twitter.api.streaming])
(ns mynamespace
(:use
[twitter.oauth]
[twitter.callbacks]
[twitter.callbacks.handlers]
[twitter.api.streaming])
(:require
[clojure.data.json :as json]
[http.async.client :as ac]
[clojure.java.io :as io])
(:import
(twitter.callbacks.protocols AsyncStreamingCallback)))
(def my-creds (make-oauth-creds *app-consumer-key*
*app-consumer-secret*
*user-access-token*
*user-access-token-secret*))
; supply a callback that only prints the text of the status
(def ^:dynamic
*custom-streaming-callback*
(AsyncStreamingCallback. (comp println #(:text %) json/read-json #(str %2))
(comp println response-return-everything)
exception-print))
(statuses-filter :params {:track "mary rose"}
:oauth-creds my-creds
:callbacks *custom-streaming-callback*)
(def mary (statuses-filter :params {:track "mary rose"}
:oauth-creds my-creds
:callbacks *custom-streaming-callback*))
如果我这样做:
(ns mynamespace
(:use
[twitter.oauth]
[twitter.callbacks]
[twitter.callbacks.handlers]
[twitter.api.streaming])
(:require
[clojure.data.json :as json]
[http.async.client :as ac]
[clojure.java.io :as io])
(:import
(twitter.callbacks.protocols AsyncStreamingCallback)))
(def my-creds (make-oauth-creds *app-consumer-key*
*app-consumer-secret*
*user-access-token*
*user-access-token-secret*))
; supply a callback that only prints the text of the status
(def ^:dynamic
*custom-streaming-callback*
(AsyncStreamingCallback. (comp println #(:text %) json/read-json #(str %2))
(comp println response-return-everything)
exception-print))
(statuses-filter :params {:track "mary rose"}
:oauth-creds my-creds
:callbacks *custom-streaming-callback*)
(def mary (statuses-filter :params {:track "mary rose"}
:oauth-creds my-creds
:callbacks *custom-streaming-callback*))
我得到了http响应的映射:
(keys mary)
;; (:id :url :raw-url :status :headers :body :done :error)
我认为身体部位是不断更新的部位:
(class @(:body mary))
;; java.io.ByteArrayOutputStream
并尝试将流保存到文件:
(with-open [r @(:body (statuses-filter :params {:track "mary rose"}
:oauth-creds my-creds
:callbacks *custom-streaming-callback*))
w (io/writer "mary.txt")]
(dosync (.write w (str r "\n"))))
这会写入第一条到达mary.txt文件的tweet,但随后会关闭连接-可能是因为我在与r的绑定前面使用了@(但如果我在desync中将@放在r前面,它会阻塞)。此外,如果我这样做:
@(dosync (:body (statuses-filter :params {:track "mary rose"}
:oauth-creds my-creds
:callbacks *custom-streaming-callback*)))
同样,在连接关闭之前,我只收到第一条推文
如何保持连接打开以继续无限期地接收推文?您应该将“写入”代码放入该回调中:
(let [w (io/writer "mary.txt")
callback (AsyncStreamingCallback.
(fn [_resp payload]
(.write w (-> (str payload) json/read-json :text))
(.write w "\n"))
(fn [_resp]
(.close w))
(fn [_resp ex]
(.close w)
(.printStackTrace ex)))]
(statuses-filter
:params {:track "mary rose"}
:oauth-creds my-creds
:callbacks callback))