0

RailsとNokogiriを使用していくつかのXMLフィードを解析しています。

1つのXMLフィードを解析しましたが、複数のフィードを解析して、日付でアイテムを並べ替えたいと思います。それらは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> 

上記のコードは正常に機能します。複数のフィードを解析しようとしましたが、404エラーが発生しました:

  feeds = %w(wordpressfeed1, wordpressfeed2)
  docs = feeds.each { |d| Nokogiri::XML(open(d)) }

1つのXMLフィードの場合と同じように、複数のフィードを解析してハッシュに追加するにはどうすればよいですか?ページの読み込み時に一度に約50のXMLフィードを解析する必要があります。

4

1 に答える 1

3

私はそれをすべて異なって書くでしょう。

indexURLの配列を受け入れるように変更してから、を使用してそれらをループし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

これは、不正なURLであり、別の問題である404エラーを修正しません。配列を正しく定義していません:

%w(wordpressfeed1, wordpressfeed2)

する必要があります:

%w(wordpressfeed1 wordpressfeed2)

また:

['wordpressfeed1', 'wordpressfeed2']

編集:

私はこのページを再訪していて、気づきました:

ページの読み込み時に一度に約50のXMLフィードを解析する必要があります。

これは、他のサイト、特に50のサイトからデータを取得する場合に、状況を処理するための完全に、絶対に間違った方法です。

WordPressサイトには通常、ニュース(RSSまたはAtom)フィードがあります。フィードには、ページを更新してもよい頻度を示すパラメータが含まれている必要があります。その間隔を尊重し、それよりも頻繁にページにアクセスしないようにします。特に、読み込みをHTMLページの読み込みまたは更新に結び付ける場合はそうです。

理由はたくさんありますが、禁止されないように「やらないでください」に分類されます。他に何もないとしても、Webページの更新を使用してサイトにDOS攻撃を仕掛けるのは簡単であり、その結果、どちらも優れたWeb開発者ではないサイトを打ち負かすことになります。あなたは最初に自分自身を守り、彼らはそれを継承します。

では、50のサイトを取得し、応答を速くして、他のサイトを打ち負かしたくない場合はどうしますか?データをデータベースにキャッシュし、ページがロードまたは更新されたときにそこから読み取ります。また、バックグラウンドで、リフレッシュレートを尊重しながら、他のサイトをスキャンするために定期的に起動する別のタスクがあります。

于 2013-01-23T00:46:56.470 に答える