我正在使用Rails和Nokogiri来解析一些XML提要。
我已经解析了一个XML Feed,我想解析多个Feed并按日期对项目进行排序。它们是Wordpress提要,因此它们具有相同的结构。
在我的控制器中我有:
def index
doc = Nokogiri::XML(open('http://somewordpressfeed'))
@content = doc.xpath('//item').map do |i|
{'title' => i.xpath('title').text, 'url' => i.xpath('link').text, 'date' => i.xpath('pubDate').text.to_datetime}
end
end
在我看来,我有:
<ul>
<% @content.each do |l| %>
<li><a href="<%= l['url'] %>"><%= l['title'] %></a> ( <%= time_ago_in_words(l['date']) %> )</li>
<% end %>
</ul>
上面的代码可以正常工作。我试图解析多个feed并得到404错误:
feeds = %w(wordpressfeed1, wordpressfeed2)
docs = feeds.each { |d| Nokogiri::XML(open(d)) }
如何解析多个Feed并将其添加到Hash中,就像我使用一个XML Feed一样?我需要在页面加载时一次解析大约50个XML提要。
答案 0 :(得分:3)
我会用不同的方式写出来。
尝试更改index
以接受一系列网址,然后使用map
对其进行循环,将结果连接到您返回的数组:
def index(*urls)
urls.map do |u|
doc = Nokogiri::XML(open(u))
doc.xpath('//item').map do |i|
{
'title' => i.xpath('title').text,
'url' => i.xpath('link').text,
'date' => i.xpath('pubDate').text.to_datetime
}
end
end
end
@content = index('url1', 'url2')
对于您的哈希键,使用符号而不是字符串会更像Ruby:
{
:title => i.xpath('title').text,
:url => i.xpath('link').text,
:date => i.xpath('pubDate').text.to_datetime
}
此外:
feeds = %w(wordpressfeed1, wordpressfeed2)
docs = feeds.each { |d| Nokogiri::XML(open(d)) }
each
是错误的迭代器。您需要map
,它将返回所有已解析的DOM,并将它们分配给docs
。
这不会修复404错误,这是一个错误的URL,并且是一个不同的问题。您没有正确定义数组:
%w(wordpressfeed1, wordpressfeed2)
应该是:
%w(wordpressfeed1 wordpressfeed2)
或:
['wordpressfeed1', 'wordpressfeed2']
编辑:
我正在重新访问此页面并注意到:
我需要在页面加载时一次解析大约50个XML Feed。
在处理从其他网站获取数据时,完全绝对是处理这种情况的错误方法,尤其是其中50个。
WordPress网站通常有新闻(RSS或Atom)Feed。 Feed中应该有一个参数说明刷新页面的确定频率。 HONOR,间隔并且不会经常访问其页面,特别是当您将负载绑定到HTML页面加载或刷新时。
原因有很多,但它会分解为“只是不要这样做”,以免被禁止。如果不出意外,使用网页刷新对您的网站进行DOS攻击是微不足道的,因此它会击败他们的网站,这对您来说都不是一个好的网络开发者。你先保护自己,然后继承自己。
那么,当你想要获得50个网站并且响应速度快而不打败其他网站时,你会怎么做?您将数据缓存在数据库中,然后在加载或刷新页面时从中读取数据。并且,在后台,您还有另一项任务,定期触发扫描其他站点,同时尊重其刷新率。