如何使用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 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

然而,我不认为这会打开第1页的每个链接,以获得下一级的fq.gz结尾文件。

我感兴趣的链接格式是:

<td><a href="/lablink/secure/DownloadFile.do?id=900636">SLX-7998.blabla.fq.gz</a></td>

我试着使用这个代码,它是根据下面的一个答案改编的,但没有下载任何东西,我得到了下面的数组

master_page.links_with(:href => /ViewSample/).map {|link| link.click
link = agent.get(agent.page.uri.to_s)
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
=> [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]

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

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$/] }

此时,nodes是与文本中的/fq.gz$/模式匹配的节点的NodeSet:

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")]
#       })]

我们可以遍历这些,只提取href参数:

hrefs = nodes.map{ |node| node['href'] }

生成一个可以迭代的数组:

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

你应该能够弄清楚剩下的。

听起来你可以使用机械化,这是一种自动与使用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

相关内容

  • 没有找到相关文章

最新更新