我想从Twitter数据扩展网址,并且(同时)提取他们的域名。我之前在Python中使用请求尝试过这样做,但我想我搞砸了,因为绝大多数URL仍处于“短”状态(bit.ly,goo.gl等)我有Twitter数据存储为JSON。我正在使用clj-http.client :as client
来解析网址。到目前为止,我的代码看起来像这样:
(defn expand-urls [urls] (for [url-str urls]
(and url-str (last (:trace-redirects
(client/get url-str))))))
(def ^:dynamic *domain-pat* (re-pattern #"https?://([\w\.]+)/.*"))
(defn get-domains [urls] (for [url urls] (first (filter #(not= url %1)
(re-find *domain-pat* url)))))
我的Twitter数据格式为[tweet-id [{tweet-data-map} {user-data-map}]]
,因此(get-in json-data [1 0 "urls"]
会返回网址,(get-in json-data [1 0 "domains"])
会返回域名。
当我尝试(update-in (update-in js-line [1 0 "urls"] expand-urls) [1 0 "domains"] get-domains)
之类的内容时,domains
为(nil)
。我已独立验证我的正则表达式是否有效,所以我怀疑问题是expand-urls
返回的延迟序列在get-domains
被调用的时间内没有进行评估。令人沮丧的是,(type (doall (expand-urls some-urls)))
和clojure.lang.LazySeq
一样返回(type (doall (doall (expand-urls some-urls))))
。我已尝试doall
,我尝试将vec
添加到expand-urls
。似乎都没有用。
这真的是一个懒惰的问题,还是我错过了其他的东西?
答案 0 :(得分:0)
您可以将解决方案重写为
(defn expand-urls [urls] (
(mapv #(last (:trace-redirects (client/get %))
(remove nil? urls)))
假设您不希望在结果中使用nils。 Mapv是惰性映射的严格对应物,总是返回一个向量。
答案 1 :(得分:-1)
解决了!关键是在doall
中添加expand-urls
:
(defn expand-urls [urls] (vec (doall (for [url-str urls]
(and url-str (last (:trace-redirects
(client/get url-str))))))))
(vec
实际上并不是必需的,但我打算重新序列化这些内容,并且不想担心org.clojure/data.json如何翻译列表。)
感谢大家的帮助!我很高兴这里有一个充满活力的clojure支持社区:)