终极 Ruby 爬虫技术栈:从 Nokogiri 到 Ferrum
Source: Dev.to

决策树
- 页面直接返回 HTML 吗? → 使用 Nokogiri。
- 是 JavaScript 单页应用(SPA)吗? → 在 Network 面板 中查找 API。
- 数据被复杂的 JS/用户交互隐藏吗? → 使用 Ferrum。
- 要抓取成千上万的页面吗? → 使用 Kimurai。
第 1 级:速度之王(HTTP + Nokogiri)
如果数据在源码(查看源代码)中,就不要把事情搞得复杂。Nokogiri 是基于 C 扩展的解析器,速度极快。
技术栈: 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 了。它慢且需要笨重的 “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 的强大功能。
class MySpider < Kimurai::Base
@name = "ecommerce_spider"
@engine = :mechanize # 或 :ferrum
@start_urls = ["https://store.com/products"]
def parse(response, url:, data: {})
response.css(".product-card").each do |product|
# 在此处理数据
end
end
end
MySpider.crawl!
严肃抓取者的专业技巧
使用 “Search” 而非 “CSS”
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。
你遇到过最难抓取的网站是什么?在评论里一起解决吧!👇