如何在 Ruby 中跨 类 使用用户输入?

How to use user input across classes in Ruby?

我正在编写一个应用程序,可以抓取 genius.com 向用户显示前十首歌曲。然后用户可以选择一首歌来查看歌词。

我想知道如何在我的爬虫 class.

的方法中使用我的 cli class 中收集的用户输入

现在我有一部分刮擦发生在刮板之外 class,但我想要一个清晰的责任划分。

这是我的部分代码:

Class CLI

def get_user_song 
  chosen_song = gets.strip.to_i
  if chosen_song > 10 || chosen_song < 1
  puts "Only the hits! Choose a number from 1-10."
end

我希望能够执行以下操作。

Class Scraper

def self.scrape_lyrics
  page = Nokogiri::HTML(open("https://genius.com/#top-songs")) 
  @url = page.css('div#top-songs a').map {|link| link['href']}
  user_selection = #input_from_cli #<---this is where I'd like to use the output 
  # of the 'gets' method above.

  @print_lyrics = @url[user_selection - 1]
  scrape_2 = Nokogiri::HTML(open(@print_lyrics))
  puts scrape_2.css(".lyrics").text
end 

我基本上想知道如何将选择的歌曲变量传递到 Scraper class。我已经尝试了一种编写 class 的方法,但是在编写它时遇到了问题,该方法不会破坏我程序的其余部分。

感谢您的帮助!

我看到了两种可能解决您的问题的方法。哪一个适合于此取决于您的设计目标。我将尝试解释每个选项:

  • 从简单阅读您的代码来看,用户在没有看到页面内容的情况下输入数字(通过您的程序)。在这种情况下,简单的方法是将选定的数字作为参数传递给 scrape_lyrics 方法:

    def self.scrape_lyrics(user_selection)
      page = Nokogiri::HTML(open("https://genius.com/#top-songs")) 
      @url = page.css('div#top-songs a').map {|link| link['href']}
      @print_lyrics = @url[user_selection -1]
      scrape_2 = Nokogiri::HTML(open(@print_lyrics))
      puts scrape_2.css(".lyrics").text
    end 
    

    所有排序都在 CLI 中进行 class,并且在开始时使用所有必要的数据调用爬虫。

  • 当想象您的工具更具交互性时,我认为让抓取工具下载当前前 10 名并将列表呈现给用户以供选择可能会很有用。在这种情况下,交互更多 back-and-forth。 如果您仍然想要严格分离,可以将 scrape_lyrics 拆分为 scrape_top_tenscrape_lyrics_by_number(song_number),然后在 CLI 中将其排序 class。 如果您希望交互流非常动态,那么将交互方法注入抓取程序并反转依赖关系可能会更好:

    def self.scrape_lyrics(cli)
      page = Nokogiri::HTML(open("https://genius.com/#top-songs")) 
      titles = page.css('div#top-songs h3:first-child').map {|t| t.text}
      user_selection = cli.choose(titles) # presents a choice to the user, returning the selected number
    
      @url = page.css('div#top-songs a').map {|link| link['href']}
      @print_lyrics = @url[user_selection - 1]
      scrape_2 = Nokogiri::HTML(open(@print_lyrics))
      puts scrape_2.css(".lyrics").text
    end 
    

    请参阅 tty-prompt gem 以获取后一种方法的示例实现。