2012-04-09 1 views
0

Этот волшебный скрипт 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 

Любые идеи о том, как сделать эту работу?

+0

Я предполагаю, что вы имели в виду * расширение *, а не * префикс *, и я обновил ваш вопрос, чтобы это отразить. –

+0

@AndrewMarshall, спасибо, спасибо. Префикс - это часть слова, добавленная к началу. – SHUMAcupcake

+0

Как предупреждение всем, кто использует вышеуказанный код; Как написано, у него есть возможность получить один и тот же URL несколько раз, тратя время и пропускную способность. Обычно для страницы есть несколько ссылок на другие страницы на сайте, и каждый из них будет посещаться, поскольку код перебирает теги ''. Поскольку требование OPs предназначено для XML-файлов, перечисленных на странице, это, вероятно, позволит избежать этой проблемы, но другие использования кода, вероятно, не будут настолько удачными. Добавьте 'set', который отслеживает ранее полученные URL-адреса, или сначала просматривает страницу для URL-адресов, и сохраняет их в наборе, а затем перебирает по ней. –

ответ

1

Я предполагаю, что атрибуты 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 
+0

Я бы рекомендовал кодировать несколько более защитно: 'file_name = File.basename (src.value, File.extname (src.value)) + extension' будет защищать от имени файла с расширением, независимо от того, что он есть, желаемый '.xml''.Без этого вы могли бы получить удвоенные расширения имен файлов, такие как '.xml.xml''. –

+0

Согласен, и, кроме того, я понял, что этот сценарий не будет работать, учитывая проблему, поставленную в вопросе. Я скоро вернусь с редактированием. –

+0

Готово. Это должно загрузить файл, используя его исходное имя файла, и сохранить его с расширением '.XML'. –

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's File класс. Он позволяет работать с файлами и путями довольно независимым от ОС образом.

dirname Его, basename и extname методы удобны, когда рассекает пути:

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 метод, который сочетает в себе dirname и basename, возвращая как путь и «filename.ext», что позволяет использовать параллельное назначение:

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

File.basename принимает необязательный параметр «расширение», что позволяет ему сдирать в extensi на:

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

Объедините все, что магическое совершенство и вы можете сбросить, шпинделя и калечить ваши имена файлов и пути в течение всего дня.

+0

+1 для обучения нас чему-то :) –