Выдать HTTP GET из REPL в Racket
Мне кажется, что я что-то пропустил, но после просмотра документов для net/url и тряски в целом мне не удалось выяснить способ отправки запроса GET из интерактивного приглашения. В принципе, я хочу подражать моему рабочему процессу python для поиска по сайту:
response = urlopen("http://www.someurl.com")
Это возможно в Racket?
Ответы
Ответ 1
Использование call/input-url
имеет несколько преимуществ:
- Вам не нужно закрывать порт самостоятельно.
- Порт закрыт, даже если есть исключение.
- Его третий аргумент
(input-port? -> any/c)
- то есть функция, которая принимает input-port
и возвращает что-либо. В дополнение к функции, которую вы пишете сами, это может быть уже определенная функция, такая как port->string
, read-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. Поэтому предложение Оскара для определения вашей собственной функции url-open
является хорошим. Реализация его с использованием call/input-url
была бы предпочтительнее, я думаю.
Ответ 2
Попробуйте следующее:
(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
EDIT:
Следуя за превосходным советом @GregHendershott (см. его ответ), еще один, более надежный способ реализовать желаемую функциональность:
(define (urlopen url)
(call/input-url
(string->url url)
(curry get-pure-port #:redirections 5)
port->string))