+1

Job Board Scraping với Rails

Dữ liệu liên quan đến công việc(jobs) là một trong những dữ liệu yêu thích của nhiều người. Mặc dù có một số public database tuyệt vời với thông tin liên quan đến công việc, nhưng nó cũng có thể được thu thập từ nhiều trang khác nhau.

Trong bài viết này mình xây dựng một bảng công việc trong Ruby on Rails sẽ tự động chạy một lần mỗi ngày, được lưu trữ miễn phí trên Heroku.

Setup

Giả sử bạn đã cài đặt thành công Ruby, Rails và DB. Hãy tạo một project mới hoặc cd tới một project có sẵn của bạn nhé !

rails new scrape_app -d postgresql
cd scrape_app/

Ở đây mình dùng postgresql để phía dưới deploy production lên heroku dễ dàng hơn. Các bạn chọn bất kì DB nào cũng được 😄.

Nếu sử dụng thêm gem đừng quên bundle install nhé !

Configure the Database

Mở file /config/database.yml và update lại như sau:

default: &default
  adapter: postgresql
  encoding: unicode
  host: localhost
  username: xxx # fill in your username
  password: xxx # fill in your password
  port: 5432
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: scrape_app_development
  
production:
  <<: *default
  database: scrape_app_production
  username: scrape_app
  password: <%= ENV['SCRAPE_APP_DATABASE_PASSWORD'] %>

Replace xxx thành username/password posgres của bạn. Tiếp theo chạy lệnh rails db:create để tạo database.

Create the ORM Model

Dùng scaffold để tạo model Job cho nhanh rails g scaffold Jobs title:string company:string url:string location:string

Ta sẽ được file này db/migrate/20200813034505_create_jobs.rb

class CreateJobs < ActiveRecord::Migration[5.2]
  def change
    create_table :jobs do |t|
      t.string :title
      t.string :company
      t.string :url
      t.string :location

      t.timestamps
    end
  end
end

Chạy rails db:migrate để rails tạo bảng và các thuộc tính cho ta nhá.

Create a Rake Task

Trong /lib/tasks tạo mới một file tên scrape.rake. Khi bạn muốn viết code và đặt lịch cho nó chạy thì đây là nơi đặt đoạn mã đó.

Ở đây mình sẽ crawl các việc làm tốt nhất của topcv nha. Update file scrape.rake :

task scrape: :environment do
  require 'open-uri'
 
  # Link mình muốn vào
  URL_BASIC = 'https://www.topcv.vn/viec-lam-tot-nhat'

  # Cho Nokogiri open url và inspect nó
  doc_basic = Nokogiri::HTML(open(URL_BASIC))
  
  # Đếm số trang cần crawl
  pages = doc_basic.search('ul.pagination > li').count - 2

  # Bắt đầu crawl từng page với index là i
  (1..pages).each do |i|
    URL = "https://www.topcv.vn/viec-lam-tot-nhat?page=#{i}"
    doc = Nokogiri::HTML(open(URL))
    postings = doc.search('div.result-job-hover')

    postings.each do |p|
      # Lấy thông tin từng field mình mong muốn theo tag html
      job_title = remove_n_string(p.search('div > div > h4.job-title > a > span.bold.transform-job-title').text)
      url = remove_n_string(p.search('div > div > h4.job-title > a')[0]['href'])
      company = remove_n_string(p.search('div > div > div.row-company').text)
      location = remove_n_string(p.search('div > div > div#row-result-info-job > div.address')[0].text)

      # Bỏ qua các job đã tồn tại trong database
      if Job.where(title: job_title, location: location, company: company).count <= 0
        Job.create(
          title: job_title,
          location: location,
          company: company,
          url: url
        )
        puts 'Added: ' + (job_title ? job_title : '')
      else
        puts 'Skipped: ' + (job_title ? job_title : '')
      end
    end
  end
end

# Loại bỏ \n chứa trong string
def remove_n_string string
  string.gsub("\n","")
end

Nokogiri là thư viện parsing html của Ruby, bài viết này sẽ không đề cập tới việc sử dụng gem này. Hãy tham khảo ở đây nhé.

Run Locally

Now let's get started - nhào vô chạy code nào rake scrape

Sau khi chạy xong, bạn có thể xem data dưới local của bạn bằng PGAdmin, DBeaver hoặc console ...

Vấn đề duy nhất của chúng ta là không muốn chạy thủ công mỗi ngày. Để khắc phục điều đó bằng cách deploy lên Heroku và schedule task. Nếu bạn có sẵn server thì dùng Whenever, sidekiq để lập schedule cũng được.

Deploy to Production

Mặc định bạn đã có account của heroku và push code lên github hoặc gitlab.

Tạo mới 1 app ở dashboard

Vào tab Deploy > App connected to GitHub > Chọn repo và nhánh của mình > Manual deploy > Chọn Deploy

Quá trình deploy có thể diễn ra vài phút.

Configure Scheduler in Production

Bây giờ chúng ta cần config rake task trên thành scheduled job. Trong tab của Heroku chọn Tab Resources > Tìm kiếm addon Heroku Scheduler > Add Addon đó vào project của bạn.

Lưu ý: Tuy addon này miễn phí nhưng heroku vẫn bắt bạn set Billing nhé.

Mở Heroku Scheduler tiến hành config như sau :

Lưu ý 2 : Giờ config là giờ UTC nhé. Ở đây mình set 6:30AM UTC tức là 1:30 PM +7

Lưu ý quan trọng: Đừng cố tình crawl data liên tục trang của người khác khi không cần thiết nếu bạn không muốn site của họ chặn IP của bạn 😂😂😂

Và đây là thành quả của mình

References


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.