Acesse a resposta HTTP como string em Go

123

Gostaria de analisar a resposta de uma solicitação da web, mas estou tendo problemas para acessá-la como string.

func main() {
    resp, err := http.Get("http://google.hu/")
    if err != nil {
        // handle error
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)

    ioutil.WriteFile("dump", body, 0600)

    for i:= 0; i < len(body); i++ {
        fmt.Println( body[i] ) // This logs uint8 and prints numbers
    }

    fmt.Println( reflect.TypeOf(body) )
    fmt.Println("done")
}

Como posso acessar a resposta como string? ioutil.WriteFilegrava corretamente a resposta em um arquivo.

Já verifiquei a referência do pacote, mas não é realmente útil.

Tibor Szasz
fonte

Respostas:

221

bs := string(body) deve ser o suficiente para lhe dar uma corda.

A partir daí, você pode usá-lo como uma string regular.

Um pouco como neste tópico :

var client http.Client
resp, err := client.Get(url)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusOK {
    bodyBytes, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    bodyString := string(bodyBytes)
    log.Info(bodyString)
}

Veja também GoByExample .

Como comentado abaixo (e em zzn de resposta ), esta é uma conversão (ver especificação ).
Consulte " Quanto custa []byte(string)? " (Problema inverso, mas a mesma conclusão se aplica), onde zzzz mencionou:

Algumas conversões são iguais a um elenco, como uint(myIntvar), que apenas reinterpreta os bits no lugar.

Sonia acrescenta:

Fazer uma string a partir de uma fatia de byte definitivamente envolve alocar a string no heap. A propriedade de imutabilidade força isso.
Às vezes, você pode otimizar fazendo o máximo de trabalho possível com [] byte e, em seguida, criando uma string no final. O bytes.Buffertipo geralmente é útil.

VonC
fonte
Obrigado. Você tem alguma sugestão de como eu poderia ter descoberto isso sozinho? Como string () faz isso? Por que não consigo ver com reflect.TypeOf?
Tibor Szasz
1
@TiborSzasz É uma conversão simples: veja blog.golang.org/slices#TOC_12 .
VonC
Uma pequena melhoria em seu código seria usar em http.StatusOKvez do 200valor bruto !
Shadoninja 01 de
Tenho feito isso e descobri que meus corpos de solicitação sempre têm um caractere de nova linha no final. Isso é normal para um corpo de solicitação ou isso é provocado por ioutil.ReadAll()??
sixty4bit
29

O método que você está usando para ler a resposta do corpo http retorna uma fatia de byte:

func ReadAll(r io.Reader) ([]byte, error)

documentação oficial

Você pode converter []bytepara uma string usando

body, err := ioutil.ReadAll(resp.Body)
bodyString := string(body)
tsabsch
fonte
1

string (byteslice) irá converter a fatia de byte em string, apenas saiba que não é apenas uma simples conversão de tipo, mas também uma cópia de memória.

zzn
fonte