У Ruby, Net::HTTP та Mechanize спрощують використання проксі, дозволяючи пряме налаштування хоста, порту та облікових даних для автентифікації проксі під час ініціалізації об'єкта або встановлення з'єднання. Ці бібліотеки дозволяють Ruby-додаткам маршрутизувати мережеві запити через проміжні проксі-сервери, підтримуючи такі сценарії використання, як ротація IP-адрес, геотаргетинг та обхід обмежень швидкості запитів.
Налаштування проксі для Net::HTTP
Net::HTTP — це стандартна бібліотека Ruby для виконання HTTP-запитів. Вона надає прямий контроль над параметрами з'єднання, включаючи налаштування проксі.
Прямі параметри проксі
Щоб налаштувати проксі для запиту Net::HTTP, вкажіть хост, порт, ім'я користувача та пароль проксі під час створення об'єкта Net::HTTP або під час запуску з'єднання.
require 'net/http'
require 'uri'
# Proxy details
proxy_host = 'your_proxy_host.com'
proxy_port = 8080
proxy_user = 'proxy_username'
proxy_pass = 'proxy_password'
# Target URL
uri = URI('http://example.com/data')
# Method 1: Specify proxy parameters in Net::HTTP.new
http = Net::HTTP.new(uri.host, uri.port, proxy_host, proxy_port, proxy_user, proxy_pass)
http.use_ssl = (uri.scheme == 'https') # Required for HTTPS
request = Net::HTTP::Get.new(uri.request_uri)
begin
response = http.request(request)
puts "Method 1 Response Status: #{response.code}"
# puts response.body
rescue Net::HTTPClientException => e
puts "HTTP Error: #{e.message}"
rescue Net::ReadTimeout, Net::OpenTimeout => e
puts "Timeout Error: #{e.message}"
rescue StandardError => e
puts "An error occurred: #{e.message}"
ensure
http.finish if http.started? # Ensure connection is closed
end
# Method 2: Specify proxy parameters in Net::HTTP.start block
uri_https = URI('https://api.ipify.org?format=json') # A simple endpoint to check IP
Net::HTTP.start(uri_https.host, uri_https.port,
proxy_host, proxy_port, proxy_user, proxy_pass,
use_ssl: uri_https.scheme == 'https') do |http_with_proxy|
request_https = Net::HTTP::Get.new(uri_https.request_uri)
response_https = http_with_proxy.request(request_https)
puts "Method 2 Response Status: #{response_https.code}"
puts "External IP via proxy: #{response_https.body}" # Should show proxy's IP
rescue Net::HTTPClientException => e
puts "HTTP Error: #{e.message}"
rescue Net::ReadTimeout, Net::OpenTimeout => e
puts "Timeout Error: #{e.message}"
rescue StandardError => e
puts "An error occurred: #{e.message}"
end
Змінні середовища
Net::HTTP може автоматично визначати налаштування проксі зі змінних середовища. Цей підхід підходить для системного або загальноприкладного налаштування проксі без зміни коду.
http_proxy: Для HTTP-запитів (наприклад,http://user:pass@proxy.example.com:8080)https_proxy: Для HTTPS-запитів (наприклад,https://user:pass@proxy.example.com:8080)no_proxy: Список імен хостів, розділених комами, які повинні обходити проксі.
require 'net/http'
require 'uri'
# Set environment variables (example, typically done outside the script)
# ENV['http_proxy'] = 'http://proxy_username:proxy_password@your_proxy_host.com:8080'
# ENV['https_proxy'] = 'http://proxy_username:proxy_password@your_proxy_host.com:8080' # Note: https_proxy can also be an http proxy
# ENV['no_proxy'] = 'localhost,127.0.0.1'
uri = URI('http://example.com/data')
http = Net::HTTP.new(uri.host, uri.port) # No explicit proxy parameters
request = Net::HTTP::Get.new(uri.request_uri)
# If http_proxy/https_proxy are set, Net::HTTP will use them.
begin
response = http.request(request)
puts "Env Var Response Status: #{response.code}"
rescue StandardError => e
puts "An error occurred: #{e.message}"
end
# Clear environment variables after use if set programmatically
# ENV.delete('http_proxy')
# ENV.delete('https_proxy')
Налаштування проксі для Mechanize
Mechanize — це Ruby-гем, який спрощує веб-скрейпінг, емулюючи веб-браузер. Він побудований на базі Net::HTTP і пропонує API вищого рівня для роботи з проксі.
Прямі параметри проксі
Mechanize дозволяє встановлювати деталі проксі під час ініціалізації агента або шляхом виклику методу set_proxy.
require 'mechanize'
# Proxy details
proxy_host = 'your_proxy_host.com'
proxy_port = 8080
proxy_user = 'proxy_username'
proxy_pass = 'proxy_password'
# Method 1: Initialize Mechanize with proxy parameters
agent = Mechanize.new do |a|
a.set_proxy(proxy_host, proxy_port, proxy_user, proxy_pass)
a.user_agent_alias = 'Mac Safari' # Recommended for web scraping
end
begin
page = agent.get('http://example.com/')
puts "Method 1 Mechanize Page Title: #{page.title}"
rescue Mechanize::ResponseCodeError => e
puts "Mechanize HTTP Error: #{e.response_code} - #{e.page.uri}"
rescue Mechanize::Error => e
puts "Mechanize Error: #{e.message}"
rescue StandardError => e
puts "An error occurred: #{e.message}"
end
# Method 2: Pass proxy parameters directly to Mechanize.new (simpler for one-off)
agent_direct = Mechanize.new(proxy_addr: proxy_host,
proxy_port: proxy_port,
proxy_user: proxy_user,
proxy_pass: proxy_pass)
agent_direct.user_agent_alias = 'Linux Firefox'
begin
page_direct = agent_direct.get('https://api.ipify.org?format=json')
puts "Method 2 Mechanize External IP via proxy: #{page_direct.body}"
rescue Mechanize::ResponseCodeError => e
puts "Mechanize HTTP Error: #{e.response_code} - #{e.page.uri}"
rescue Mechanize::Error => e
puts "Mechanize Error: #{e.message}"
rescue StandardError => e
puts "An error occurred: #{e.message}"
end
Ротація проксі за допомогою Mechanize
Для сценаріїв, що вимагають частих змін IP-адрес, таких як великомасштабний збір даних, ротація проксі є важливою. Метод set_proxy Mechanize можна викликати кілька разів, щоб змінити проксі протягом життєвого циклу агента.
```ruby
require 'mechanize'
proxies = [
{ host: 'proxy1.example.com', port: 80