Подтвердить что ты не робот

Загрузить изображение с URL-адреса?

Я пытаюсь использовать HTTP:: get для загрузки изображения диаграммы Google из созданного мной URL-адреса.

Это была моя первая попытка:

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

Создал только пустой файл PNG.

Для моей второй попытки я использовал значение, хранящееся внутри failure_url внутри вызова http.get().

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

И по какой-то причине эта версия работает, даже если первая попытка имела те же данные внутри вызова http.get(). Кто-нибудь знает, почему это?

РЕШЕНИЕ:

Попытавшись понять, почему это происходит, я нашел "Как загрузить бинарный файл через HTTP?".

В одном из комментариев упоминается удаление http:// в вызове Net::HTTP.start(...), иначе это не будет выполнено. Конечно, после того, как я это сделал:

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

он работал.

4b9b3361

Ответ 1

Я бы пошел за файлом, используя Ruby Open:: URI:

require "open-uri"

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

Причина, по которой я предпочитаю Open:: URI, автоматически обрабатывает перенаправления, поэтому КОГДА Google вносит изменения в свой внутренний сервер и пытается перенаправить URL-адрес, код будет обрабатывать его магически. Он также обрабатывает таймауты и повторяет попытку, если я правильно помню.

Если у вас должен быть более низкий уровень управления, я бы посмотрел на один из многих других HTTP-клиентов для Ruby; Net:: HTTP отлично подходит для создания новых сервисов или когда клиент не существует, но я бы использовал Open:: URI или что-то помимо Net:: HTTP, пока не возникнет необходимость.


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

нарушает URI. Я подозреваю, что он видит символы, которые должны быть закодированы в URL-адресах.

В целях документации, вот что говорит URI при попытке разобрать этот URL-адрес:

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

Если я сначала кодирую URI, я получаю успешный синтаксический анализ. Далее тестирование с использованием Open:: URI показывает, что оно может получить документ в этой точке и возвращает 23701 байт.

Я думаю, что это подходящее решение для проблемы, если некоторые из этих символов действительно неприемлемы для URI, и они находятся вне RFC.

Просто для информации, Addressable:: URI gem - отличная замена встроенного URI.

Ответ 2

    resp = http.get("/chart?#{failures_url")

Если вы скопировали исходный код, вам не хватает закрывающей фигурной скобки в вашей строке пути.

Ответ 3

В исходной версии не было имени параметра для каждого параметра, а только данных. Например, в заголовке вы не можете просто отправить "Builds + in + the + last + 12 + months", но вместо этого он должен быть "chtt = Builds + in + the + last + 12 + months".

Попробуйте следующее:

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