2017-09-01 5 views
0

J'essaie de télécharger des données CSV à partir d'une URL. La réponse brute ressemble à ceComment lire une pièce jointe à partir d'une réponse HTTP

HTTP/1.1 200 OK 
Server: Europa-4 
X-Varnish: 33948791 
Vary: Accept-Encoding, X-UA-Device 
X-Cache: MISS 
Cache-Control: no-cache, no-cache, no-store, proxy-revalidate, must-revalidate, max-age=0 
Content-Type: application/octet-stream 
P3p: CP="CAO PSA OUR" 
Date: Fri, 01 Sep 2017 19:53:27 GMT 
X-Server: web03 
Expires: Fri, 01 Sep 2017 19:53:26 GMT 
X-XSS-Protection: 1; mode=block 
Transfer-Encoding: chunked 
Accept-Ranges: bytes 
X-Content-Type-Options: nosniff 
Content-Disposition: attachment; filename="GooglePLAv1US.txt" 
Via: 1.1 varnish-v4 
Connection: keep-alive 
Last-Modified: Fri, 01 Sep 2017 19:53:27 +0000 
X-Frame-Options: sameorigin 
X-UA-Device: desktop 
Age: 0 
X-Modified-Url: /amfeed/main/get/file/GooglePLAv1US/?___store=ca_en 

id  title description  google_product_category ..... 
20649074  ...... 
20652632  ...... 
. 
. 
. 

Maintenant, je me rends compte ce n'est pas vraiment une réponse à plusieurs parties, mais il a l'en-tête Content-Disposition: attachment; filename="GooglePLAv1US.txt", qui dit qu'il doit être traité en téléchargement par le navigateur.

Lorsque j'essaie de lire le corps de la réponse, il génère l'erreur unexpected EOF. Comment puis-je lire ces données, ce n'est pas vraiment dans une section?

code

http.DefaultClient.Timeout = time.Second * 30 
resp, err := http.Get(ht.Creds.AccessData.URL) 
if err != nil { 
    return nil, err 
} 
defer resp.Body.Close() 
d, err := ioutil.ReadAll(resp.Body) 
if err != nil { 
    return nil, errors.Wrap(err, "Error reading HTTP response body") 
} 

Ce produit l'erreur

Error reading HTTP response body: unexpected EOF 
+0

C'est dans la réponse. Corps, en supposant que vous utilisez Go (basé sur les balises de question), mais vous n'avez montré aucun code, donc il n'y a pas beaucoup d'aide que n'importe qui peut offrir. – Adrian

+0

@Adrian a soumis le code que j'utilise, merci! – Danish

Répondre

0

donner un essai à net/textproto, voici un petit exemple:

package main 

import (
    "bufio" 
    "fmt" 
    "io" 
    "net/http" 
    "net/http/httptest" 
    "net/textproto" 
    "os" 
) 

func main() { 
    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
     fmt.Fprintf(w, "%s\n%s\n%s\n%s\n", 
      "col1,col2,col3", 
      "1,2,3", 
      "a,b,c", 
      "x,y,x", 
     ) 
    })) 
    defer ts.Close() 

    client := &http.Client{} 
    res, err := client.Get(ts.URL) 
    if err != nil { 
     fmt.Fprintln(os.Stderr, err) 
     return 
    } 
    defer res.Body.Close() 
    reader := bufio.NewReader(res.Body) 
    tp := textproto.NewReader(reader) 
    for { 
     if line, err := tp.ReadLine(); err != nil { 
      if err == io.EOF { 
       // if file is emtpy 
       return 
      } 
      return 
     } else { 
      fmt.Printf("%s\n\n", line) 
     } 
    } 
} 

https://play.golang.org/p/fee4B5mh35

Voici un autre exemple en fonction de votre question initiale concernant « csv »:

package main 

import (
    "bufio" 
    "fmt" 
    "net/http" 
    "os" 
) 

func main() { 
    client := &http.Client{} 
    res, err := client.Get("http://samplecsvs.s3.amazonaws.com/Sacramentorealestatetransactions.csv") 
    if err != nil { 
     fmt.Fprintln(os.Stderr, err) 
     return 
    } 
    defer res.Body.Close() 
    scanner := bufio.NewScanner(res.Body) 
    scanner.Split(bufio.ScanBytes) 
    for scanner.Scan() { 
     c := scanner.Text() 
     switch c { 
     case "\r": 
      fmt.Println() 
     default: 
      fmt.Printf("%s", c) 
     } 
    } 
} 

Dans ce cas, notez le scanner.Split(bufio.ScanBytes), espérons que cela peut vous donner plus d'idées.

+0

Donc, intéressant, même mon avec mon code d'origine, si je vérifie pour err == io. ErrUnexpectedEOF' et l'ignorer, les données téléchargées sont exactement comme celles téléchargées par le navigateur. – Danish

+0

Avez-vous déjà essayé https://golang.org/pkg/mime/multipart/? – nbari