我想通过这种方式下载音乐文件:
require 'open-uri' source_url = "http://soundcloud.com/stereo-foo/cohete-amigo/download" attachment_file = "test.wav" open(attachment_file,"wb") do |file| file.print open(source_url).read end
在该示例中,我想将“Test.wav”更改为真实文件名(例如JDownloader程序).
编辑:我不是指临时文件,我的意思是像Jdownloader这样的网络存储文件得到:“Cohete Amigo – Stereo Foo.wav”
谢谢你的阅读
更新:
我试过这个来存储这个名字:
attachment_file = File.basename(open(source_url))
我认为这没有任何意义,但我不知道如何做到这一点,对不起.
解决方法
文件名存储在名为Content-Disposition的标题字段中.但是解码这个字段可能有点棘手.请参阅此处的一些讨论:
How to encode the filename parameter of Content-Disposition header in HTTP?
对于open-uri,您可以通过返回的File类的meta
访问器访问所有头字段:
f = open('http://soundcloud.com/stereo-foo/cohete-amigo/download') f.Meta['content-disposition'] => "attachment;filename=\"Stereo Foo - Cohete Amigo.wav\""
所以为了解码这样的东西,你可以这样做:
cd = f.Meta['content-disposition']. filename = cd.match(/filename=(\"?)(.+)\1/)[2] => "Stereo Foo - Cohete Amigo.wav"
它适用于您的特定情况,如果引号“不存在,它也可以工作.但在更复杂的内容处理情况下,如UTF-8文件名,您可能会遇到一些麻烦.不确定使用UTF-8的频率虽然,即使soundcloud使用UTF-8.所以也许你不需要担心(没有确认也没有测试过).
您还可以使用更高级的网络爬行框架,如Mechanize
,并相信它可以为您解码:
require 'mechanize' agent = Mechanize.new file = agent.get('http://soundcloud.com/stereo-foo/cohete-amigo/download') file.filename => "Stereo_Foo_-_Cohete_Amigo.wav"