13

我觉得我遗漏了一些东西,但是在阅读了 net/url 的文档并大致浏览了一遍之后,我无法找到一种从交互式提示中发出 GET 请求的方法。基本上,我想模仿我的 python 工作流程来浏览网站:

response = urlopen("http://www.someurl.com")

这在球拍中可行吗?

4

2 回答 2

13

使用call/input-url有几个优点:

  • 您不需要自己关闭端口。
  • 即使有异常,端口也会关闭。
  • 它的第三个参数是(input-port? -> any/c)——也就是说,一个接受input-port并返回任何东西的函数。除了您自己编写的函数之外,它还可以是已经定义的函数,例如port->stringread-html-as-xml等。

例如:

(call/input-url (string->url "http://www.google.com/")
                get-pure-port
                port->string)

注意:当我输入这个答案时,我注意到 Óscar 编辑了他的重定向。我的类似编辑是:

(call/input-url (string->url "http://www.google.com/")
                (curry get-pure-port #:redirections 4)
                port->string)

当然,在 REPL 中频繁输入任何一种方式仍然相当冗长。所以 Óscar 定义自己的url-open函数的建议是一个很好的建议。我认为使用它来实现它call/input-url会更好。

于 2013-05-22T19:47:25.160 回答
7

试试这个:

(require net/url)

(define input (get-pure-port (string->url "http://www.someurl.com")))
(define response (port->string input))
(close-input-port input)

现在该response变量将包含来自服务器的 http 响应。更好的是,将上述内容打包到一个过程中,还请注意我添加了允许的最大重定向数:

(define (urlopen url)
  (let* ((input (get-pure-port (string->url url) #:redirections 5))
         (response (port->string input)))
    (close-input-port input)
    response))

(urlopen "http://www.someurl.com") ; this will return the response

编辑:

遵循@GregHendershott 的出色建议(有关详细信息,请参阅他的答案),这是实现所需功能的另一种更强大的方法:

(define (urlopen url)
  (call/input-url
   (string->url url)
   (curry get-pure-port #:redirections 5)
   port->string))
于 2013-05-22T18:12:02.233 回答