2013-05-22 11 views
13

Czuję, że czegoś brakuje, ale po przeczytaniu dokumentów dla net/url i ogólnie mówiąc, nie byłem w stanie wymyślić sposobu na wysłanie żądania GET z interaktywny monit. Zasadniczo, chcę naśladować mój przepływ pracy w języku Python, aby zaglądać na stronę internetową:Wystąpił błąd HTTP z REPL w przekrętce

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

Czy to możliwe w grze?

Odpowiedz

12

Korzystanie call/input-url ma kilka zalet:

  • Nie musisz sam zamykać portu.
  • Port jest zamknięty, nawet jeśli istnieje wyjątek.
  • Trzeci argument to (input-port? -> any/c) - czyli funkcja, która pobiera input-port i zwraca wszystko. Oprócz funkcji, którą sam napiszesz, może to być już zdefiniowana funkcja, taka jak port->string, read-html-as-xml i tak dalej.

Na przykład:

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

Uwaga: Jak pisałem tę odpowiedź, zauważam, że Oscar edytowany His zrobić przekierowań. Moja podobna edycja to:

Oczywiście, w obu przypadkach nadal jest dość gęsty, aby pisać często w REPL. Sugestia Óscara do zdefiniowania własnej funkcji jest bardzo dobra. Wdrożenie go przy użyciu call/input-url byłoby lepsze, jak sądzę.

+1

Czy istnieje sposób na wyodrębnienie kodu statusu innego niż przetwarzanie nagłówków "ręcznie"? Jestem zaskoczony, że nie mogłem znaleźć żadnej funkcji pomocniczej, która by to zrobiła, albo w przekręcie właściwym, albo w bibliotece http. – offby1

+0

Niestety, nie zauważyłem nawet Twojego komentarza do tej pory! Moja http lib zawiera następujące funkcje: https://github.com/greghendershott/http/blob/master/http/head.rkt#L22-L45 –

7

Spróbuj tego:

(require net/url) 

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

Teraz zmienna response będzie zawierać odpowiedzi HTTP z serwera. Nawet lepiej, opakowanie wyżej w procedurze, również zauważyć, że dodałem maksymalną liczbę przekierowań dozwolony:

(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:

Following @ doskonałą poradę GregHendershott (patrz jego odpowiedź szczegóły) oto kolejny, bardziej wydajny sposób wdrożyć żądaną funkcjonalność:

(define (urlopen url) 
    (call/input-url 
    (string->url url) 
    (curry get-pure-port #:redirections 5) 
    port->string)) 
Powiązane problemy