Ruby 如何从Nokogiri页面下载特定链接

Ruby 如何从Nokogiri页面下载特定链接,ruby,nokogiri,Ruby,Nokogiri,我有一个网页,上面有一个名字列表(是常规链接)。当我单击第一个页面的名称时,会打开另一个页面,其中有一个文件列表,可作为链接下载。我只想下载所有page1链接中以fq.qz结尾的链接 为此,我一直在尝试使用Nokogiri: require 'nokogiri' require 'open-uri' url = 'http://myURL/' doc = Nokogiri::HTML(open(url)) puts doc.css('li')[2]['href'] doc.traverse

我有一个网页,上面有一个名字列表(是常规链接)。当我单击第一个页面的名称时,会打开另一个页面,其中有一个文件列表,可作为链接下载。我只想下载所有page1链接中以fq.qz结尾的链接

为此,我一直在尝试使用Nokogiri:

require 'nokogiri'
require 'open-uri'

url = 'http://myURL/'
doc = Nokogiri::HTML(open(url))
puts doc.css('li')[2]['href']

doc.traverse do |el|
    [el[:src], el[:href]].grep(/\.(fq.gz)$/i).map{|l| URI.join(url, l).to_s}.each do |link|
        File.open(File.basename(link),'wb'){|f| f << open(link,'rb').read}
    end
end

听起来您可以使用它,这是一个自动化与使用Nokogiri作为依赖项的网页交互的工具。您可能可以这样做:

require 'mechanize'

$agent      = Mechanize.new
master_page = $agent.get("http://master_page")

master_page.search("a.download_list_link") do |download_list_link|
  download_list_page = $agent.get(download_list_link[:href])

  download_list_page.search("td > a") do |link|
    if link.content.include?("fq.gz")
      out_file = File.new("downloaded_file", "w")
      out_file.puts($agent.get_file(link[:href]))
      out_file.close
    end
  end
end
我在那里写的一些东西将取决于您访问的页面上元素的具体名称,但我认为这里的总体思路将解决您的问题

编辑:

关于使用
nil
对象数组时出现的错误,我看到的一个问题是您忘记关闭块:

master_page.links_with(:href => /ViewSample/).map {|link| link.click
...
# no terminating curly brace

这是快速搜索链接文本中包含特定子字符串的锚的基础:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<a href="http://foo">foo.fq.gz</a>
<a href="http://bar">bar.fq.gz</a>
<a href="http://baz">baz</a>
EOT

nodes = doc.search('a').select{ |node| node.text[/fq\.gz$/] }
我们可以浏览这些内容并仅提取
href
参数:

hrefs = nodes.map{ |node| node['href'] }
生成一个可以迭代的数组:

hrefs
# => ["http://foo", "http://bar"]

您应该能够找出其余的问题。

那么,您是在给定页面上查找这些下载链接时遇到问题,还是在为它们下载/写入文件时遇到问题?因此,我在尝试从第1页遍历每个页面,然后从超链接下载哪个页面是第1页时遇到问题?因为你提到了两种类型的页面;一页用于查找文件列表,另一页用于查找可供下载的实际文件列表。第1页是页面列表,该列表上的每一页都是第2页,其中包含可供下载的文件列表。如果我理解正确,您无法从每个可下载文件列表中找到所有下载链接,也无法将下载链接的内容下载/写入文件?确定。小呃逆。如果我需要添加身份验证,我是否只需在代码的第三行之后添加代理?当我这样做的时候,作为#@SebastianZeki的一部分,这个问题可能值得一看:@SebastianZeki你最终通过身份验证取得了什么进展吗?我并不是想强求别人;只是好奇。是的,谢谢你的提问。我的红宝石非常糟糕,所以我花了几个小时试图解决这个问题。必须更改您的代码,因此请参见上面我创建的代码。在它当前的形式中,我得到了一个错误。@SebastianZeki我看到你的代码中有一个即时错误;相应地更新了我的答案。
nodes
# => [#(Element:0x3fd9818bda2c {
#       name = "a",
#       attributes = [
#         #(Attr:0x3fd982027060 { name = "href", value = "http://foo" })],
#       children = [ #(Text "foo.fq.gz")]
#       }),
#     #(Element:0x3fd9818bd928 {
#       name = "a",
#       attributes = [
#         #(Attr:0x3fd982035ef8 { name = "href", value = "http://bar" })],
#       children = [ #(Text "bar.fq.gz")]
#       })]
hrefs = nodes.map{ |node| node['href'] }
hrefs
# => ["http://foo", "http://bar"]