【问题标题】:How do I add an extension to a file when downloading it?下载文件时如何为文件添加扩展名?
【发布时间】:2012-04-09 15:21:57
【问题描述】:

这个神奇的 Ruby 脚本从网站下载几个 XML 文件,但这些文件没有扩展名。我想为它下载的每个文件添加前缀.xml

这就是我现在的位置,它不会工作:

require 'rubygems'
require 'nokogiri'
require 'open-uri'

URL = 'localhost'
extension = '.xml'

Nokogiri::HTML(open(URL)).xpath("//a/@href").each do |src|
  src = File.join(extension).last
  File.open(File.basename(src),'wb') do |f| 
    f.write(open(src).read)
  end
  puts "Done with: #{URL}"
end

关于如何完成这项工作的任何想法?

【问题讨论】:

  • 我假设您的意思是 extension,而不是 prefix,我已经更新了您的问题以反映这一点。
  • @AndrewMarshall,是的,谢谢伙计。前缀是添加到开头的单词部分。
  • 作为对使用上述代码的任何人的警告;正如所写,它有可能多次检索相同的 URL,浪费时间和带宽。一个页面通常有多个指向站点上其他页面的链接,并且每个链接都将在代码循环通过<a> 标记时被访问。因为 OPs 要求是针对页面中列出的 XML 文件,所以可能会避免该问题,但代码的其他用途可能不会那么幸运。添加一个set 来跟踪之前检索到的 URL,或者先扫描页面中的 URL 并将它们存储在集合中,然后对其进行迭代。
  • @theTinMan 是的,代码有点懒。

标签: ruby open-uri


【解决方案1】:

File.join() 的使用是错误的。 .join() 返回一个字符串,然后对它应用.last 会产生错误,因为String 对象没有.last 方法。

pry(main)> extension = '.xml'
=> ".xml"
pry(main)> File.join(extension).last
NoMethodError: undefined method `last' for ".xml":String

相反,您需要将要加入的路径元素数组传递到文件的路径中:

pry(main)> File.join('.', 'path', 'to', 'a', 'file.ext')
=> "./path/to/a/file.ext"

或:

pry(main)> File.join('/', 'path', 'to', 'a', 'file.ext')
=> "/path/to/a/file.ext"

花时间阅读 Ruby 的 File 类。它允许您以完全独立于操作系统的方式处理文件和路径。

它的dirnamebasenameextname方法在剖析路径时很方便:

pry(main)> File.dirname('/path/to/a/file.ext')
=> "/path/to/a"
pry(main)> File.basename('/path/to/a/file.ext')
=> "file.ext"
pry(main)> File.extname('/path/to/a/file.ext')
=> ".ext" 

还有split 方法结合了dirnamebasename,同时返回路径和“filename.ext”,让您可以使用并行赋值:

pry(main)> dirname, filename = File.split('/path/to/a/file.ext')
=> ["/path/to/a", "file.ext"]

File.basename 采用可选的“扩展”参数,允许它剥离扩展:

pry(main)> File.basename('/path/to/a/file.ext', '.ext')
=> "file"

结合所有这些神奇的优点,您可以整天折叠、旋转和破坏您的文件名和路径。

【讨论】:

    【解决方案2】:

    我假设您页面链接中的href 属性包含绝对路径。考虑到这一点,这应该工作。

    require 'rubygems'
    require 'nokogiri'
    require 'open-uri'
    
    base_url = 'localhost'
    extension = '.xml'
    
    Nokogiri::HTML(open(base_url)).xpath("//a/@href").each do |src|
      File.open(File.basename(src.value, File.extname(src.value)) + extension,'wb'){ |f| 
        f.write(open(src.value).read)
      }
      puts "Done with: #{URL}"
    end
    

    【讨论】:

    • 我建议编码得更加防御性:file_name = File.basename(src.value, File.extname(src.value)) + extension 将防止带有扩展名的文件名,无论它是什么,同时仍添加所需的'.xml'。否则,您最终可能会得到双倍的文件扩展名,例如 '.xml.xml'
    • 同意,此外,考虑到问题中提出的问题,我意识到这个脚本不起作用。我很快就会回来编辑。
    • 完成。这应该使用其原始文件名下载文件,并将其保存为 .XML 扩展名。
    • 好东西@loannis Karadimas.. 但我收到以下语法错误:
    • 一个流氓paren())是罪魁祸首。修好了。
    猜你喜欢
    • 1970-01-01
    • 2016-09-06
    • 1970-01-01
    • 2011-09-01
    • 2015-09-08
    • 1970-01-01
    • 2013-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多