解析页面上的所有链接,访问它们,提取正文副本,然后继续有效地遍历



这就是我的内容:

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)来创建映射。

相关内容

  • 没有找到相关文章

最新更新