Greifen Sie in Go auf die HTTP-Antwort als Zeichenfolge zu

122

Ich möchte die Antwort einer Webanforderung analysieren, habe jedoch Probleme, als Zeichenfolge darauf zuzugreifen.

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")
}

Wie kann ich als Zeichenfolge auf die Antwort zugreifen? ioutil.WriteFileschreibt die Antwort auf eine Datei korrekt.

Ich habe die Paketreferenz bereits überprüft, aber sie ist nicht wirklich hilfreich.

Tibor Szasz
quelle

Antworten:

220

bs := string(body) sollte ausreichen, um Ihnen eine Zeichenfolge zu geben.

Von dort aus können Sie es als regulären String verwenden.

Ein bisschen wie in diesem Thread :

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)
}

Siehe auch GoByExample .

Wie unten (und in der Antwort von zzn ) kommentiert , handelt es sich um eine Konvertierung (siehe Spezifikation ). Siehe " Wie teuer ist ? " (Umgekehrtes Problem, aber die gleiche Schlussfolgerung gilt), wo zzzz erwähnte:
[]byte(string)

Einige Konvertierungen sind mit einer Besetzung identisch uint(myIntvar), bei der nur die vorhandenen Bits neu interpretiert werden.

Sonia fügt hinzu:

Das Erstellen einer Zeichenfolge aus einem Byte-Slice umfasst definitiv das Zuweisen der Zeichenfolge auf dem Heap. Die Unveränderlichkeitseigenschaft erzwingt dies.
Manchmal können Sie optimieren, indem Sie so viel Arbeit wie möglich mit [] Byte erledigen und am Ende eine Zeichenfolge erstellen. Der bytes.BufferTyp ist oft nützlich.

VonC
quelle
Vielen Dank. Haben Sie einen Vorschlag, wie ich es selbst hätte herausfinden können? Wie macht string () das? Warum kann ich es mit Reflect.TypeOf nicht sehen?
Tibor Szasz
1
@TiborSzasz Es ist eine einfache Konvertierung: siehe blog.golang.org/slices#TOC_12 .
VonC
Eine kleine Verbesserung Ihres Codes wäre die Verwendung http.StatusOKanstelle des Rohwerts 200!
Shadoninja
Ich habe dies getan und festgestellt, dass meine Anforderungskörper am Ende immer ein Zeilenumbruchzeichen haben. Ist das normal für einen Anfragetext oder wird das von verursacht ioutil.ReadAll()?
Sixty4bit
29

Die Methode, mit der Sie die http-Textantwort lesen, gibt ein Byte-Slice zurück:

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

offizielle Dokumentation

Sie können []bytemithilfe von in einen String konvertieren

body, err := ioutil.ReadAll(resp.Body)
bodyString := string(body)
Tsabsch
quelle
1

string (byteslice) konvertiert Byte Slice in String. Sie müssen nur wissen, dass es sich nicht nur um eine Typkonvertierung handelt, sondern auch um eine Speicherkopie.

zzn
quelle