这就是我的内容:
require 'rubygems'
require 'nokogiri'
require 'open-uri'
root_url = "http://boxerbiography.blogspot.com/2006/11/table-of-contents.html"
file_path = "boxer-noko.html"
site = Nokogiri::HTML(open(root_url))
titles = []
content = []
site.css(".entry a").each do |link|
titles.push(link)
content_url = link[:href]
content_page = Nokogiri::HTML(open(content_url))
content_page.css("#top p").each do |copy|
content.push(copy)
end
end
但这是n^n个循环。例如,如果主页上有5个链接,它会去到第一个,然后在content
中,它会将所有5个链接的值赋给它(当前链接在顶部),然后它会返回到下一个,并继续这样做。
所以每个内容实际上返回每个链接的内容,看起来像这样:
Link 1
Copy associated with Link 1.
Copy associated with Link 2.
Copy associated with Link 3.
.
.
.
Link 2
Copy associated with Link 2.
Copy associated with Link 3.
Copy associated with Link 4.
Copy associated with Link 5.
Copy associated with Link 1.
.
.
.
etc.
我想让它做的是返回这个:
Link 1
Copy associated with Link 1.
Link 2
Copy associated with Link 2.
以尽可能有效的方式。
我该怎么做?
Edit1:我想一个简单的方法来考虑这一点是,在每个数组中,说titles
,我想存储链接和与该链接相关的内容。但不太确定如何做到这一点,因为我必须打开两个URI连接来解析两个页面并不断返回根目录。
所以我把它想象成:
title[0] = :href => "http://somelink.com", :content => "Copy associated with some link".
但不能完全得到它,所以我被迫使用两个数组,这对我来说似乎是次优的。
下面将用URL键创建一个散列,每个URL的值是Nokogiri段落元素的集合。
require 'rubygems'
require 'nokogiri'
require 'open-uri'
root_url = "http://boxerbiography.blogspot.com/2006/11/table-of-contents.html"
site = Nokogiri::HTML(open(root_url))
contents = {}
site.css(".entry a").each do |link|
content_url = link[:href]
p "Fetching #{content_url}..."
content_page = Nokogiri::HTML(open(content_url))
contents[link[:href]] = content_page.css("#top p")
end
作为完整性检查,您可以像这样检查其中一个键的内容:
contents[contents.keys.first]
这可能是或可能不是你真正想要的,因为它会保持所有的内部标签到位(<br/>
s, <i>...</i>
s等),但这可以很容易地通过改变内容的收集方式来调整。也可以通过后处理每个URL的内容来处理。
如果你想保存关于每个URL的更多信息(比如链接的文本),那么你可能需要创建一个带有URL和title属性的小包装器类。
目前,代码没有做任何检查来确保每个URL只被检索一次——最好创建URL的Set
来强制惟一性,然后通过遍历该集合的内容(URL)来创建映射。