如何从URL下载每个zip文件并使用rails

时间:2016-10-18 13:54:37

标签: ruby-on-rails ruby zip

现在我有一个URL,其中填充了浏览器中的.zip文件列表。我正在尝试使用rails下载文件,然后使用Zip::File gem中的rubyzip打开它们。目前我正在使用typhoeus gem:

这样做
response = Typhoeus.get("http://url_with_zip_files.com")

但是response.response_body是字符串中的HTML文档。我是编程的新手,所以使用最佳实践在正确的方向上提示会有很多帮助。

response.response_body => "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n<html>\n <head>\n  <title>Index of /mainstream/posts</title>\n </head>\n <body>\n<h1>Index of /mainstream/posts</h1>\n<table><tr><th><a href=\"?C=N;O=D\">Name</a></th><th><a href=\"?C=M;O=A\">Last modified</a></th><th><a href=\"?C=S;O=A\">Size</a></th><th><a href=\"?C=D;O=A\">Description</a></th></tr><tr><th colspan=\"4\"><hr></th></tr>\n<tr><td><a href=\"/5Rh5AMTrc4Pv/mainstream/\">Parent Directory</a></td><td>&nbsp;</td><td align=\"right\">  - </td><td>&nbsp;</td></tr>\n<tr><td><a href=\"1476536091739.zip\">1476536091739.zip</a></td><td align=\"right\">15-Oct-2016 16:01  </td><td align=\"right\"> 10M</td><td>&nbsp;</td></tr>\n<tr><td><a href=\"1476536487496.zip\">1476536487496.zip</a></td><td align=\"right\">15-Oct-2016 16:04  </td><td align=\"right\"> 10M</td><td>&nbsp;</td></tr>"

2 个答案:

答案 0 :(得分:2)

为了解决这个问题,你需要:

  1. 使用Typhoeus获取初始HTML索引页

      base_url = "http://url_with_zip_files.com/"
      response = Typhoeus.get(base_url)
    
  2. 然后使用Nokogiri解析该HTML以提取zip文件的所有链接(请参阅:extract links (URLs), with nokogiri in ruby, from a href html tags?

    doc = Nokogiri::HTML(response)
    links = doc.css('a').map { |link| link['href'] }
    links.map { |link| base_url + '/' + link}
    
    # Should look like:
    # links = ["http://url_with_zip_files.com/1476536091739.zip", "http://url_with_zip_files.com/1476536487496.zip" ...]
    
    # The first link is a link to Parent Directory which you should probably drop 
    # looks like: "/5Rh5AMTrc4Pv/mainstream/"
    
    links.pop
    
  3. 获得所有链接:然后访问所有提取的链接以使用ruby下载zip文件并解压缩(请参阅:Ruby: Download zip file and extract

     links.each do |link|
       download_and_parse(link)
     end
    
     def download_and_parse(zip_file_link)
       input = Typhoeus.get(zip_file_link).body
       Zip::InputStream.open(StringIO.new(input)) do |io|
          while entry = io.get_next_entry
              puts entry.name
              parse_zip_content io.read
          end
       end
     end
    
  4. 如果您想使用Typhoeus将文件内容从网址流式传输到内存,请参阅标题为“流式传输响应正文”的Typhoeus文档部分。你也可以使用Typhoeus下载paralell中的所有文件,这样可以提高你的表现。

答案 1 :(得分:1)

我相信Nokogiri是你最好的选择。

base_url = "http://url_with_zip_files.com/"
doc = Nokogiri::HTML(Typhoeus.get(base_url))
zip_array = []
doc.search('a').each do |link| 
  if link.attr("href").match /.+\.zip/i
   zip_array << Typhoeus.get(base_url + link.attr("href"))
  end
end