2016-07-12 4 views
0

私は、多くのWebサイトでは通常同じCSSセレクタに基づいてデータを抽出するいくつかの「汎用」メソッドを持っています。しかし、私は引数として指定されたWebサイトのCSSセレクタを受け入れる別の方法があります。Rubyメソッドの条件付き引数

title_selector引数が渡された場合は、get_titleメソッドを呼び出す必要があります。どうやってやるの?

スクレイプ引数

def scrape(urls, item_selector, title_selector, price_selector,  image_selector) 
    collection = [] 
    urls.each do |url| 
     doc = Nokogiri::HTML(open(url).read) # Opens URL 
     @items = doc.css(item_selector)[0..1].map {|item| item['href']} # Sets items 
     @items.each do |item| # Donwload each link and parse 
     page = Nokogiri::HTML(open(item).read) 
     collection << { 
      :title => page.css(title_selector).text, # I guess I need conditional here 
      :price => page.css(price_selector).text 
     } 
     end 
     @collection = collection 
    end 
    end 

ジェネリックタイトル抽出

def get_title(doc) 
    if doc.at_css("meta[property='og:title']") 
     title = doc.css("meta[property='og:title']") 
    else doc.css('title') 
     title = doc.at_css('title').text 
    end 
    end 

答えて

2

があなたのpage.cssコール内or演算子を使用してCSSセレクタを受け入れます。 title_selectorがfalse(nil)の場合、get_titleを呼び出します。

:title => page.css(title_selector || get_title(doc)).text, 

私はdocは実際にかかわらず、この文脈でどうあるべきかわかりません。以下のコメントを考えると

EDIT

は、私はあなただけのロジックのすべてを処理するためにget_titleをリファクタリングすることができると思います。 get_titleはオプションtitle_selectorのパラメータを取り、あなたの方法の先頭に次の行を追加することを許可する:

return doc.css(title_selector).text if title_selector 

その後、私の元の行は次のようになります。

:title => get_title(page, title_selector) 
+0

慎重に。 '.text'はそれらのうちの1つでのみ呼び出され、1つは' css'で、もう1つは 'at_css'です。 – tadman

+0

うーん、私はよく説明していないと思う。 page.css()内の引数は、 '#title> .title-class> h1'のようなCSSセレクタです。したがってget_title(doc)は、get_titleがスクラップされたタイトルページ( 'Amazon.com ...)を返すので、これは機能しません.cssセレクタ。 FYI doc = Nokogiri形式のフルHTMLソース。 Thks。 –

+0

ああ、あなたの説明は良かったです。私の読解力は不足していた。私は*私の編集はそれを今カバーするべきだと思う。 – Johnson

関連する問題