我有一个网页,上面有一系列名称(它们是常规链接)。当我点击第一个页面的名称时,这会打开另一个页面,其中有一个文件列表作为链接下载。我只想下载所有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