webentwicklung-frage-antwort-db.com.de

Ein Bild von einer URL herunterladen?

Ich versuche HTTP :: get zu verwenden, um ein Bild eines Google-Diagramms von einer von mir erstellten URL herunterzuladen.

Dies war mein erster Versuch:

failures_url  = [title, type, data, size, colors, labels].join("&")

require 'net/http'

Net::HTTP.start("http://chart.googleapis.com") { |http|
  resp = http.get("/chart?#{failures_url")
  open("pie.png" ,"wb") { |file|
    file.write(resp.body)
  }
}

Wodurch nur eine leere PNG-Datei erzeugt wurde.

Für meinen zweiten Versuch habe ich den Wert verwendet, der in failure_url innerhalb des http.get()-Aufrufs gespeichert ist.

require 'net/http'

Net::HTTP.start("http://chart.googleapis.com") { |http|
  resp = http.get("/chart?chtt=Builds+in+the+last+12+months&cht=bvg&chd=t:296,1058,1217,1615,1200,611,2055,1663,1746,1950,2044,2781,1553&chs=800x375&chco=4466AA&chxl=0:|Jul-2010|Aug-2010|Sep-2010|Oct-2010|Nov-2010|Dec-2010|Jan-2011|Feb-2011|Mar-2011|Apr-2011|May-2011|Jun-2011|Jul-2011|2:|Months|3:|Builds&chxt=x,y,x,y&chg=0,6.6666666666666666666666666666667,5,5,0,0&chxp=3,50|2,50&chbh=23,5,30&chxr=1,0,3000&chds=0,3000")
  open("pie.png" ,"wb") { |file|
    file.write(resp.body)
  }
}

Und aus irgendeinem Grund funktioniert diese Version, obwohl beim ersten Versuch die gleichen Daten im Aufruf http.get() enthalten waren. Weiß jemand warum das so ist?

LÖSUNG:

Nachdem ich versucht hatte herauszufinden, warum dies passiert, fand ich " Wie lade ich eine Binärdatei über HTTP herunter? ".

In einem der Kommentare wird erwähnt, dass http:// im Net::HTTP.start(...)-Aufruf entfernt wird, da dies sonst nicht erfolgreich ist. Sicher genug, nachdem ich das getan habe:

failures_url  = [title, type, data, size, colors, labels].join("&")

require 'net/http'

Net::HTTP.start("chart.googleapis.com") { |http|
  resp = http.get("/chart?#{failures_url")
  open("pie.png" ,"wb") { |file|
    file.write(resp.body)
  }
}

es funktionierte.

20
Hunter McMillen

Ich würde die Datei mit Rubys Open :: URI verfolgen:

require "open-uri"

File.open('pie.png', 'wb') do |fo|
  fo.write open("http://chart.googleapis.com/chart?#{failures_url}").read 
end

Ich bevorzuge Open :: URI, weil er Umleitungen automatisch verarbeitet. Wenn Google also eine Änderung am Backend vornimmt und versucht, die URL umzuleiten, wird der Code magisch behandelt. Es verarbeitet auch Timeouts und Wiederholungen, wenn ich mich recht erinnere.

Wenn Sie über eine untergeordnete Steuerung verfügen müssen, würde ich mir einen der vielen anderen HTTP-Clients für Ruby anschauen. Net :: HTTP eignet sich gut zum Erstellen neuer Dienste oder wenn ein Client nicht vorhanden ist, aber ich würde Open :: URI oder etwas anderes als Net :: HTTP verwenden, bis sich die Notwendigkeit ergibt.


Die URL:

http://chart.googleapis.com/chart?chtt=Builds+in+the+last+12+months&cht=bvg&chd=t:296,1058,1217,1615,1200,611,2055,1663,1746,1950,2044,2781,1553&chs=800x375&chco=4466AA&chxl=0:|Jul-2010|Aug-2010|Sep-2010|Oct-2010|Nov-2010|Dec-2010|Jan-2011|Feb-2011|Mar-2011|Apr-2011|May-2011|Jun-2011|Jul-2011|2:|Months|3:|Builds&chxt=x,y,x,y&chg=0,6.6666666666666666666666666666667,5,5,0,0&chxp=3,50|2,50&chbh=23,5,30&chxr=1,0,3000&chds=0,3000

macht URI verärgert. Ich vermute, es werden Zeichen angezeigt, die in URLs codiert sein sollten. 

Zu Dokumentationszwecken sagt Folgendes aus, wenn Sie versuchen, diese URL so zu analysieren, wie sie ist:

URI::InvalidURIError: bad URI(is not URI?)

Wenn ich den URI zuerst codiere, erhalte ich eine erfolgreiche Analyse. Weitere Tests mit Open :: URI zeigen, dass das Dokument zu diesem Zeitpunkt abgerufen werden kann, und geben 23701 Bytes zurück.

Ich denke, das ist die geeignete Lösung für das Problem, wenn einige dieser Zeichen für URIUNDwirklich nicht akzeptabel sind, da sie sich außerhalb des RFC befinden.

Nur zur Information: Addressable :: URI gem ist ein hervorragender Ersatz für die integrierte URI.

54
the Tin Man
    resp = http.get("/chart?#{failures_url")

Wenn Sie Ihren ursprünglichen Code kopiert haben, fehlt Ihnen eine schließende geschweifte Klammer in der Pfadzeichenfolge.

3
George

Ihre ursprüngliche Version hatte nicht den Parameternamen für jeden Parameter, sondern nur die Daten. Zum Beispiel können Sie beim Titel nicht einfach "Builds + in + last + 12 + months" einreichen, sondern müssen stattdessen "chtt = Builds + in + last + 12 + months" sein.

Versuche dies:

failures_url  = ["title="+title, "type="+type, "data="+data, "size="+size, "colors="+colors, "labels="+labels].join("&")
0
Jonathan M