从 URL 下载图像?

发布于 2024-11-25 11:00:26 字数 1746 浏览 1 评论 0原文

我正在尝试使用 HTTP::get 从我创建的 URL 下载 Google 图表的图像。

这是我的第一次尝试:

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 文件。

在我的第二次尝试中,我使用了 http.get() 调用中 failure_url 中存储的值。

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 下载二进制文件?"。

其中一条评论提到在 Net::HTTP.start(...) 调用中删除 http:// ,否则它将不会成功。果然,我这样做之后:

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

它起作用了。

I am trying to use HTTP::get to download an image of a Google chart from a URL I created.

This was my first attempt:

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

Which produced only an empty PNG file.

For my second attempt I used the value stored inside failure_url inside the http.get() call.

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

And, for some reason, this version works even though the first attempt had the same data inside the http.get() call. Does anyone know why this is?

SOLUTION:

After trying to figure why this is happening I found "How do I download a binary file over HTTP?".

One of the comments mentions removing http:// in the Net::HTTP.start(...) call otherwise it won't succeed. Sure enough after I did this:

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

it worked.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云巢 2024-12-02 11:00:27

来查找文件:

require "open-uri"

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

我会使用 Ruby 的 Open:: URI 我更喜欢 Open::URI 的原因是它会自动处理重定向,因此当 Google 对其后端进行更改并尝试重定向 URL 时,代码会神奇地处理它。如果我没记错的话,它还能更优雅地处理超时和重试。

如果您必须进行较低级别的控制,那么我会考虑 Ruby 的许多其他 HTTP 客户端之一; 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 的绝佳替代品。

I'd go after the file using Ruby's Open::URI:

require "open-uri"

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

The reason I prefer Open::URI is it handles redirects automatically, so WHEN Google makes a change to their back-end and tries to redirect the URL, the code will handle it magically. It also handles timeouts and retries more gracefully if I remember right.

If you must have lower level control then I'd look at one of the many other HTTP clients for Ruby; Net::HTTP is fine for creating new services or when a client doesn't exist, but I'd use Open::URI or something besides Net::HTTP until the need presents itself.


The 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

makes URI upset. I suspect it is seeing characters that should be encoded in URLs.

For documentation purposes, here is what URI says when trying to parse that URL as-is:

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

If I encode the URI first, I get a successful parse. Testing further using Open::URI shows it is able to retrieve the document at that point and returns 23701 bytes.

I think that is the appropriate fix for the problem if some of those characters are truly not acceptable to URI AND they are out of the RFC.

Just for information, the Addressable::URI gem is a great replacement for the built-in URI.

路还长,别太狂 2024-12-02 11:00:27
    resp = http.get("/chart?#{failures_url")

如果您复制了原始代码,那么您的路径字符串中缺少右大括号。

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

If you copied your original code then you're missing a closing curly bracket in your path string.

奢欲 2024-12-02 11:00:27

您的原始版本没有每个参数的参数名称,只有数据。例如,在标题上,您不能只提交“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("&")

Your original version did not have the parameter name for each parameter, just the data. For example, on the title, you cannot just submit "Builds+in+the+last+12+months", but instead it must be "chtt=Builds+in+the+last+12+months".

Try this:

failures_url  = ["title="+title, "type="+type, "data="+data, "size="+size, "colors="+colors, "labels="+labels].join("&")
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文