Tag: Feedjira/解析

目次

関連ページ

参考情報

処理の流れ

  • 通常以下のメソッドの呼び出しによってfeedが取得できる。
    feed = Feedjira::Feed.fetch_and_parse(feed_url)
  • メソッドはfeedjira/feed.rbに存在。
          def fetch_and_parse(url)
            response = connection(url).get
            unless response.success?
              raise FetchFailure, "Fetch failed - #{response.status}"
            end
            feed = parse response.body #レスポンスを解析
            feed.feed_url = url
            feed.etag = response.headers['etag'].to_s.delete '"'
    
            feed.last_modified = parse_last_modified(response)
            feed
          end
    
  • parseはFeedクラスのクラスメソッドで以下のような内容となっている(同ファイル)。
          def parse(xml, &block)
            parser = determine_feed_parser_for_xml(xml)
            raise NoParserAvailable, 'No valid parser for XML.' unless parser
            parse_with parser, xml, &block
          end
    
  • 実際のparserはURLの取得先によって切り替わる。パーサーの配列はconfiguration.rbで以下のような種類が準備されている。
        # @private
        def default_parsers
          [
            Feedjira::Parser::RSSFeedBurner,
            Feedjira::Parser::GoogleDocsAtom,
            Feedjira::Parser::AtomYoutube,
            Feedjira::Parser::AtomFeedBurner,
            Feedjira::Parser::Atom,
            Feedjira::Parser::ITunesRSS,
            Feedjira::Parser::RSS
          ]
        end
      end
    
  • rssの場合は、parser/rss.rbがそれ。
    # rubocop:disable Style/DocumentationMethod
    module Feedjira
      module Parser
        # Parser for dealing with RSS feeds.
        # Source: https://cyber.harvard.edu/rss/rss.html
        class RSS
          include SAXMachine
          include FeedUtilities
          element :description
          element :image, class: RSSImage
          element :language
          element :lastBuildDate, as: :last_built
          element :link, as: :url
          element :rss, as: :version, value: :version
          element :title
          element :ttl
          elements :"atom:link", as: :hubs, value: :href, with: { rel: 'hub' }
          elements :item, as: :entries, class: RSSEntry
    
          attr_accessor :feed_url
    
          def self.able_to_parse?(xml)
            (/\<rss|\<rdf/ =~ xml) && !(/feedburner/ =~ xml)
          end
        end
      end
    end
    
    
  • ParserにSAXMachineとFeedUtilitiesがincludeされていることに注意。SAXMachineは外部gemで、FeedUtilitiesはFeedjira内部のmoduleとなっている(moduleによってnew_entries, update, last_modifiedなどのメソッドが追加されている)。parseはSAXMachineのparseメソッドが呼び出される。
  • parseの戻り値は自身のクラスFeedjira::Parser::RSSとなる。

ポイント

last_modifiedはどこで設定される

  • fetch_and_parse内部のfeed = parse response.bodyの呼び出し直後にすでに@last_modifiedが設定されている。=>と思ったのは間違いでデバッガのwatchによって、feed.last_modifiedが評価されたタイミングで@last_modifiedに値が設定されていたのが原因っぽい。
  • @last_modifiedはSAX Machineではなくて、FeedUtilitiesで定義される通常のアクセサメソッドで、以下のようにgetterが定義されている。
        def last_modified
          puts "hereherehere"
          @last_modified ||= begin
            published = entries.reject { |e| e.published.nil? }
            entry = published.sort_by { |e| e.published if e.published }.last
            entry ? entry.published : nil
          end
        end
    
  • すなわち@last_modifiedがnilの場合、フィードに含まれるエントリーの最後のpublishedが採用されることがわかる。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-05-15 (月) 15:53:45 (704d)