Introduction
Ruby remains a strong choice for web scraping in 2026 — especially for teams already running Rails infrastructure. The Product Data Scrape engineering team has built and operated Ruby-based scrapers across 20+ marketplaces, processing 3 billion+ records last quarter. This guide shares the production patterns we use.
The Modern Ruby Scraping Stack
| Layer | 2020 Standard | 2026 Standard (Product Data Scrape) |
|---|---|---|
| HTTP client | Net::HTTP / OpenURI | Faraday / HTTParty |
| HTML parsing | Nokogiri (still king) | Nokogiri / Oga |
| Headless browser | Selenium + PhantomJS | Ferrum (CDP direct) |
| Concurrency | Thread + Mutex | Async gem / Ractor |
| Scheduling | whenever gem | Sidekiq Cron / Solid Queue |
| Storage | ActiveRecord | ActiveRecord / Kredis + PostgreSQL |
Async Patterns: The New Default
Ruby 3.x brings first-class async support through the Async gem. For anything past 10 URLs, use fiber-based concurrency:
require 'async'
require 'async/http/internet'
require 'nokogiri'
def scrape_url(internet, url)
response = internet.get(url, timeout: 15)
doc = Nokogiri::HTML(response.read)
parse_product(doc)
rescue => e
{ url: url, error: e.message }
end
def scrape_many(urls)
results = []
Async do |task|
internet = Async::HTTP::Internet.new
# Semaphore limits concurrency to 10
semaphore = Async::Semaphore.new(10)
tasks = urls.map do |url|
task.async do
semaphore.acquire do
results << scrape_url(internet, url)
end
end
end
tasks.each(&:wait)
ensure
internet&.close
end
results
end
# Usage
data = scrape_many(['url1', 'url2', 'url3'])
Error Handling Classification
Production scrapers fail in dozens of ways. Catch and categorize errors so the system can respond appropriately — retries for Faraday::TimeoutError and 5xx errors, longer waits for 429 rate-limit responses, immediate failures for 404s, and Sentry alerts for unexpected parsing exceptions. Faraday's middleware stack (faraday-retry, faraday-encoding) handles most of this declaratively.
Rate Limiting With Jitter
Constant request intervals are a giveaway to anti-bot systems. Use exponential backoff with jitter — Faraday::Retry::Middleware supports this natively via backoff_factor and randomness options. For production, use rack-attack-style token buckets. This is one of the core patterns the Product Data Scrape API uses internally.
Sample Data From Product Data Scrape Ruby API
When you use the Product Data Scrape Ruby SDK, results look like this:
require 'productdatascrape'
pds = ProductDataScrape::Client.new(api_key: ENV['PDS_API_KEY'])
result = pds.scrape('https://walmart.com/ip/12345')
# result returns:
{
"request_id" => "req_abc123xyz",
"status" => "success",
"credits_used" => 1,
"latency_ms" => 487,
"data" => {
"product_id" => "WP-12345",
"retailer" => "walmart_us",
"title" => "Apple AirPods Pro (2nd Generation)",
"brand" => "Apple",
"price" => { "current" => 199.99, "msrp" => 249.00, "currency" => "USD" },
"rating" => { "value" => 4.7, "count" => 8492 },
"availability" => "in_stock",
"scraped_at" => "2026-05-15T14:22:00Z"
}
}
How Product Data Scrape Helps
When you outgrow DIY Ruby scraping (typically around 50K+ SKUs/day or when Amazon/Cloudflare-protected targets enter the picture), the Product Data Scrape Ruby gem handles all production concerns behind a single REST endpoint — Rails engine mount for API routes, Sidekiq worker for background scraping, ActiveRecord model for cached results, and automatic proxy rotation with residential IPs.
Get 1,000 free API credits from Product Data Scrape
Contact Us Today!About Product Data Scrape
Product Data Scrape is the leading provider of managed web scraping services and ready-to-use product datasets. We help 200+ brands, retailers, and AI companies turn the messy public web into clean, structured product data.
Our Services: — Web Scraping API — REST API for developers (1,000 free credits) — Scraper as a Service — Custom scrapers built in 7-10 days — Ready Datasets — 100+ pre-built datasets, free 1,000-row samples in 24 hours
Contact: — Website: https://www.productdatascrape.com — Email: info@productdatascrape.com