궁극의 Ruby 스크래핑 스택: Nokogiri에서 Ferrum까지
Source: Dev.to

결정 트리
- 페이지가 HTML을 직접 반환하나요? → Nokogiri 사용.
- JavaScript 싱글 페이지 앱(SPA)인가요? → Network Tab에서 API를 확인.
- 데이터가 복잡한 JS/사용자 상호작용 뒤에 숨겨져 있나요? → Ferrum 사용.
- 수천 개의 페이지를 스크래핑하나요? → Kimurai 사용.
레벨 1: 스피드 킹 (HTTP + Nokogiri)
데이터가 소스 코드(보기 소스) 안에 있다면 복잡하게 만들 필요가 없습니다. Nokogiri는 C‑extension 기반 파서로 매우 빠릅니다.
스택: HTTP (gem) + Nokogiri
require 'http'
require 'nokogiri'
response = HTTP.get("https://news.ycombinator.com/")
doc = Nokogiri::HTML(response.body)
doc.css('.titleline > a').each do |link|
puts "#{link.text}: #{link['href']}"
end
왜 좋은가: 거의 메모리를 사용하지 않으며 분당 수백 페이지를 처리할 수 있습니다.
레벨 2: 현대적인 헤드리스 선택 (Ferrum)
버튼을 클릭하거나 Vue/React가 렌더링될 때까지 기다려야 한다면 Selenium 사용을 중단하세요. Selenium은 느리고 번거로운 “WebDriver” 중개자를 필요로 합니다.
**Ferrum**을 사용하면 Chrome DevTools Protocol(CDP)을 통해 직접 Chrome과 통신합니다.
require "ferrum"
browser = Ferrum::Browser.new(headless: true)
browser.goto("https://example.com/dynamic-charts")
# 특정 요소가 나타날 때까지 대기
browser.network.wait_for_idle
# 또는: browser.at_css(".data-loaded")
puts browser.at_css(".price-display").text
browser.quit
왜 좋은가: Selenium보다 빠르고, Linux에 설치가 간편하며(Chromium만 필요), 네트워크와 헤더를 세밀하게 제어할 수 있습니다.
레벨 3: 대용량 오케스트레이션 (Kimurai)
프록시, User‑Agent 회전, 멀티스레딩이 필요한 전체 규모 크롤러를 만들 때는 휠을 다시 만들지 말고 프레임워크를 사용하세요.
**Kimurai**는 Ruby에 “Scrapy‑like” 파워를 제공합니다.
class MySpider < Kimurai::Base
@name = "ecommerce_spider"
@engine = :mechanize # or :ferrum
@start_urls = ["https://store.com/products"]
def parse(response, url:, data: {})
response.css(".product-card").each do |product|
# 여기서 데이터 처리
end
end
end
MySpider.crawl!
진지한 스크래퍼를 위한 프로 팁
”CSS” 대신 “Search” 사용
Nokogiri는 xpath를 지원하며, 이는 CSS 선택자보다 강력합니다. 텍스트를 기준으로 버튼을 찾으려면:
doc.xpath("//button[contains(text(), 'Submit')]")
아이덴티티 관리
항상 현실적인 User-Agent를 설정하세요. 서버가 기본 Ruby/Faraday 에이전트를 차단할 수 있습니다.
user_agent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."
지속성
스크립트가 중단될 경우를 대비해 콘솔에 출력하는 대신 CSV 또는 JSONL로 바로 스트리밍하세요.
require 'csv'
CSV.open("data.csv", "ab") do |csv|
csv << [title, price, url]
end
윤리 체크
robots.txt확인 –Crawl-delay를 준수하세요.- DDOS 금지 –
sleep(rand(1..3))를 사용해 인간 행동을 흉내 내세요. - API 우선 – JSON API가 있다면 사용하세요; 모두에게 더 좋습니다.
요약
- 정적? Nokogiri 사용.
- 동적? Ferrum 사용.
- 대규모? Kimurai 사용.
- 똑똑하게? 숨겨진 API를 찾아라.
가장 어려웠던 사이트는 무엇인가요? 댓글에서 함께 해결해 봅시다! 👇