我试图使用OCaml的Url和Cohttp模块来访问API和检索JSON数据。我不想用异步的方式来做这件事。我对web/网络编程没有经验,所有的模块文档都只是为类型和方法提供签名(因为我不知道它们是做什么的,所以对我帮助不大)。我正在尝试访问bitstamp API并检索比特币的出价。到目前为止,我只知道如何声明URI。
let bitstamp_uri = Uri.of_string "http://www.bitstamp.net/api/ticker/";;
但是,我现在知道了如何调用uri来检索json数据。如何使用现有的库来实现这一点?我已经知道如何将json数据解析为我需要的类型。
发布于 2013-11-19 06:10:58
Cohttp要求您要么使用Lwt,要么使用异步,因此您必须学习其中一个库。幸运的是,检索JSON文本并解析它正是新的read书中的一个例子,您可以在网上免费阅读这里。第18章涉及异步和Cohttp,第15章涉及JSON解析。
现在,要真正回答你的问题:
$ utop
utop # #require "lwt.syntax";;
utop # #require "core";;
utop # open Core.Std;;
utop # #require "cohttp.lwt";;
utop # #require "uri";;
utop # let get_uri uri : string Or_error.t Lwt.t =
let open Lwt in
match_lwt Cohttp_lwt_unix.Client.get uri with
| None ->
let msg = sprintf "%s: no reply" (Uri.to_string uri) in
return (Or_error.error_string msg)
| Some (_, body) -> (
lwt body = Cohttp_lwt_body.string_of_body body in
return (Ok body)
);;
utop # let bitstamp_uri = Uri.of_string "http://www.bitstamp.net/api/ticker/";;
utop # get_uri bitstamp_uri;;
- : string Or_error.t =
Core_kernel.Result.Ok
"{\"high\": \"755.00\", \"last\": \"675.20\", \"timestamp\": \"1384841189\", \"bid\": \"675.10\", \"volume\": \"72858.24608402\", \"low\": \"471.26\", \"ask\": \"675.20\"}"
在本例中,我使用了Core和Lwt。RWO书使用异步。如果要完全避免异步编程的复杂性,则不能使用Cohttp。
发布于 2013-11-19 09:05:24
这里有一个使用Curl
的答案,它不需要您理解异步。(不过,我认为您最好还是使用异步和Cohttp!)
(* Wrapper for Curl. Used by the function below. *)
let fetch (url: string) (f: string -> int): unit =
let c = Curl.init () in
Curl.set_url c url;
Curl.set_followlocation c true;
Curl.set_writefunction c f;
Curl.perform c;
Curl.cleanup c
;;
(* [get url] fetches the document at [url] and returns its contents as a string. *)
let get (url: string): string =
let buf = Buffer.create 16 in
fetch url (fun s -> Buffer.add_string buf s; String.length s);
Buffer.contents buf
;;
发布于 2014-12-25 16:02:53
下面是另一个您可能会发现有用的例子。在本例中,我不依赖Core或异步,您应该能够将其作为脚本运行,而不是在toplevel中运行。
#! /usr/bin/env ocaml
#use "topfind"
#require "uri"
#require "cohttp.lwt"
let fetch uri =
let open Lwt in
Cohttp_lwt_unix.Client.get uri >>= fun (resp, body) ->
Cohttp_lwt_body.to_string body >>= fun b ->
Lwt_io.printl b
let () =
let bitstamp_uri = Uri.of_string "http://www.bitstamp.net/api/ticker/" in
Lwt_main.run (fetch bitstamp_uri)
https://stackoverflow.com/questions/20062627
复制相似问题