我有一个包含名单列表的网页(这是常规链接)。当我点击第一页的名称时,这将打开另一个页面,其中包含要作为链接下载的文件列表。我想只下载以fq.qz结尾的所有page1链接的链接。
要做到这一点,我一直在尝试使用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]
答案 0 :(得分:0)
您听起来像是可以使用Mechanize,这是一种自动与使用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
答案 1 :(得分:0)
这是快速搜索链接文本中包含某些子字符串的锚点的基础:
compile fileTree(dir: 'libs', include: ['*.jar'])
此时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$/
我们可以浏览这些并仅提取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'] }
你应该能够弄清楚其余部分。