架构问题 - 抓取任务放在哪里
Architecture Question - Where to put the scrape task
我目前正在构建一个应用程序,它每天只需访问一个网站,并将该网站特定 table 的信息保存到我设置的数据库中。我目前在我的模型上创建了一个 class 方法来完成抓取。我创建的 rake 任务每天调用一次 class 方法。
虽然我的代码 'works' 和我每天收集一次信息,但我觉得在我的模型中保留抓取逻辑有点奇怪,并且很好奇是否有更好的方法来完成这个任务。
class WebTable < ApplicationRecord
def self.scrape_and_save_table_information
doc = Nokogiri::HTML(open('https://www.calottery.com/play/scratchers-games/top-prizes-remaining'))
rows = doc.css("tbody tr")
rows.each do |row|
row_object = {}
row_object["cell_one"] = row.children[1].children[0].to_s
row_object["cell_two"] = row.children[2].children[0].children.to_s
row_object["cell_three"] = row.children[7].children[0].children[0].to_s
@table = WebTable.create(row_object)
end
end
end
我的佣金任务是这样的:
desc 'scraping webpages'
task scrape_web_pages: :environment do
daily_prize_scrape = WebTable.scrape_and_save_table_information
end
更好的方法是让它成为一个 ActiveJob 作业,即使你打算在没有任何后台工作人员的情况下调用它,只需使用来自 rails runner
.
的 YourTask.perform_now
它将允许您分离逻辑,而且 activejobs 比 rake 任务更容易测试。
Sidekiq worker 往往工作得很好(双关语意),特别是在循环的情况下,您可以从一个主要 worker 派生其他 worker,以获得更好的性能和更容易的错误捕获
例如
class HardWorker
include Sidekiq::Worker
def perform
['nice', 'rows'].each do |row|
OtherWorker.perform_async(row)
end
end
end
我目前正在构建一个应用程序,它每天只需访问一个网站,并将该网站特定 table 的信息保存到我设置的数据库中。我目前在我的模型上创建了一个 class 方法来完成抓取。我创建的 rake 任务每天调用一次 class 方法。
虽然我的代码 'works' 和我每天收集一次信息,但我觉得在我的模型中保留抓取逻辑有点奇怪,并且很好奇是否有更好的方法来完成这个任务。
class WebTable < ApplicationRecord
def self.scrape_and_save_table_information
doc = Nokogiri::HTML(open('https://www.calottery.com/play/scratchers-games/top-prizes-remaining'))
rows = doc.css("tbody tr")
rows.each do |row|
row_object = {}
row_object["cell_one"] = row.children[1].children[0].to_s
row_object["cell_two"] = row.children[2].children[0].children.to_s
row_object["cell_three"] = row.children[7].children[0].children[0].to_s
@table = WebTable.create(row_object)
end
end
end
我的佣金任务是这样的:
desc 'scraping webpages'
task scrape_web_pages: :environment do
daily_prize_scrape = WebTable.scrape_and_save_table_information
end
更好的方法是让它成为一个 ActiveJob 作业,即使你打算在没有任何后台工作人员的情况下调用它,只需使用来自 rails runner
.
YourTask.perform_now
它将允许您分离逻辑,而且 activejobs 比 rake 任务更容易测试。
Sidekiq worker 往往工作得很好(双关语意),特别是在循环的情况下,您可以从一个主要 worker 派生其他 worker,以获得更好的性能和更容易的错误捕获
例如
class HardWorker
include Sidekiq::Worker
def perform
['nice', 'rows'].each do |row|
OtherWorker.perform_async(row)
end
end
end