اگر شما یک پارسر مینویسید، یک API خارجی را ادغام میکنید یا جمعآوری دادهها را در Ruby خودکار میکنید — دیر یا زود با مسدودیتهای IP مواجه خواهید شد. Wildberries، Ozon، Instagram و دهها سرویس دیگر درخواستها را از یک آدرس بعد از چند صد تماس قطع میکنند. راهحل یکی است — پروکسی. در این مقاله بررسی خواهیم کرد که چگونه پروکسی را به پروژه Ruby خود از طریق Net::HTTP استاندارد و HTTP-client محبوب Faraday متصل کنیم، چرخش IP را تنظیم کنیم و خطاها را به درستی مدیریت کنیم — هم در برنامه Rails و هم در اسکریپتهای ساده.
چرا توسعهدهنده Ruby به پروکسی نیاز دارد: سناریوهای اصلی
Ruby به طور فعال برای وظایفی استفاده میشود که بدون پروکسی نمیتوان از آنها عبور کرد. قبل از اینکه به کد برویم، باید بفهمیم که در چه موقعیتهایی به آنها نیاز داریم — این به انتخاب نوع و معماری مناسب کمک میکند.
پارسر و جمعآوری دادهها. این رایجترین سناریو است. شما یک اسکریپت Ruby مینویسید که صفحات Wildberries، Ozon یا Avito را مرور میکند و قیمتها و ویژگیهای محصولات را جمعآوری میکند. بدون پروکسی، چنین اسکریپتی بعد از چند دقیقه به دلیل IP مسدود میشود. وبسایتها صدها درخواست از یک آدرس را میبینند و به طور خودکار حفاظت را فعال میکنند — CAPTCHA، مسدودیت موقت یا عدم خدمات کامل.
ادغام با APIهای وابسته به جغرافیا. برخی از سرویسهای خارجی محتواهای مختلفی را بسته به کشور درخواستکننده برمیگردانند. اگر برنامه Rails شما به چنین APIای مراجعه کند، پروکسی اجازه میدهد تا درخواستها را از منطقه مورد نظر شبیهسازی کند. به عنوان مثال، بررسی نتایج موتورهای جستجو برای کشورهای مختلف یا دریافت قیمتهای مربوط به بازار خاص.
تست و QA. توسعهدهندگان از پروکسی برای آزمایش رفتار برنامه در هنگام درخواست از IPهای مختلف و کشورها استفاده میکنند. این به ویژه برای سرویسهایی که دارای مسدودیت جغرافیایی یا محدودیت نرخ بر اساس IP هستند، مهم است.
خودکارسازی بازاریابی. اسکریپتهای Ruby اغلب برای نظارت بر کمپینهای تبلیغاتی، بررسی موقعیتها در نتایج یا پیگیری فعالیتهای رقبای خود استفاده میشوند. در اینجا پروکسی برای توزیع بار و دور زدن محدودیتها ضروری است.
کار با چندین حساب. اگر اسکریپت شما چندین حساب را در یک پلتفرم مدیریت میکند، هر حساب باید از یک IP جداگانه استفاده کند — در غیر این صورت پلتفرم به راحتی ارتباط را شناسایی کرده و همه را به طور همزمان مسدود میکند.
کدام نوع پروکسی را برای وظایف Ruby انتخاب کنیم
همه پروکسیها به یک اندازه برای وظایف مختلف مناسب نیستند. انتخاب نوع به طور مستقیم بر موفقیت کار اسکریپت شما تأثیر میگذارد. بیایید گزینههای اصلی را در زمینه توسعه Ruby بررسی کنیم.
| نوع پروکسی | بهترین وظایف در Ruby | سرعت | دور زدن حفاظتها |
|---|---|---|---|
| پروکسیهای دیتاسنتر | پارسر بدون حفاظت سخت، درخواستهای API، تست | بالا | متوسط |
| پروکسیهای مسکونی | پارسر وبسایتهای محافظتشده، کار با شبکههای اجتماعی، بازارها | متوسط | بالا |
| پروکسیهای موبایل | Facebook، Instagram، TikTok API، کار با حسابها | متوسط | حداکثر |
پروکسیهای دیتاسنتر — سریعترین و ارزانترین گزینه هستند. برای پارس کردن وبسایتها بدون حفاظتهای تهاجمی، درخواستهای API انبوه و تست بار مناسب هستند. با این حال، پلتفرمهای بزرگ (Facebook، Google، Cloudflare) به راحتی آنها را بر اساس ASN دیتاسنتر شناسایی میکنند.
پروکسیهای مسکونی از IP کاربران واقعی خانگی استفاده میکنند. برای اسکریپتهای Ruby که Wildberries، Ozon را پارس میکنند یا با وبسایتهای محافظتشده کار میکنند — این انتخاب بهینه است. وبسایتها یک کاربر عادی را میبینند، نه یک سرور.
پروکسیهای موبایل از IP اپراتورهای موبایل (4G/5G) استفاده میکنند. این آدرسها از نظر پلتفرمها معتبرترین هستند — یک IP موبایل میتواند به طور همزمان توسط صدها کاربر واقعی استفاده شود، بنابراین مسدودیتها بر اساس آن بسیار نادر است. اگر اسکریپت Ruby شما با شبکههای اجتماعی یا پلتفرمهای تبلیغاتی کار میکند — پروکسیهای موبایل خطر مسدودیتها را به حداقل میرسانند.
پروکسی در Net::HTTP: تنظیمات پایه
Net::HTTP — کتابخانه استاندارد Ruby برای درخواستهای HTTP که در بسته استاندارد زبان گنجانده شده است. این کتابخانه به طور پیشفرض پروکسی را از طریق متد خاص Net::HTTP::Proxy پشتیبانی میکند.
سادهترین راه — ایجاد یک کلاس پروکسی و استفاده از آن به جای Net::HTTP معمولی:
require 'net/http'
require 'uri'
# دادههای پروکسی
proxy_host = 'proxy.example.com'
proxy_port = 8080
# ایجاد کلاس پروکسی
proxy_class = Net::HTTP::Proxy(proxy_host, proxy_port)
# انجام درخواست از طریق پروکسی
uri = URI('https://httpbin.org/ip')
proxy_class.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
request = Net::HTTP::Get.new(uri)
response = http.request(request)
puts response.body
end
متد Net::HTTP::Proxy چهار پارامتر میپذیرد: هاست پروکسی، پورت، نام کاربری و رمز عبور. دو پارامتر اول الزامی هستند، دو پارامتر آخر برای پروکسی بدون احراز هویت اختیاری هستند.
روش جایگزین — ارسال پارامترهای پروکسی به طور مستقیم به متد Net::HTTP.new:
require 'net/http'
uri = URI('https://httpbin.org/ip')
http = Net::HTTP.new(
uri.host,
uri.port,
'proxy.example.com', # proxy_addr
8080, # proxy_port
nil, # proxy_user (nil اگر بدون احراز هویت)
nil # proxy_pass
)
http.use_ssl = true
response = http.get(uri.path)
puts response.body
این روش زمانی مناسب است که شما نیاز دارید از یک شیء HTTP یکسان برای چندین درخواست به یک هاست استفاده کنید. توجه داشته باشید: پارامترهای پروکسی به عنوان آرگومانهای سوم و چهارم ارسال میشوند، نه از طریق یک متد جداگانه.
احراز هویت و HTTPS از طریق Net::HTTP
بیشتر پروکسیهای تجاری نیاز به احراز هویت دارند — نام کاربری و رمز عبور. علاوه بر این، هنگام کار با وبسایتهای HTTPS نیاز به تنظیمات اضافی SSL است. بیایید هر دو مورد را بررسی کنیم.
پروکسی با نام کاربری و رمز عبور:
require 'net/http'
require 'uri'
proxy_host = 'proxy.example.com'
proxy_port = 8080
proxy_user = 'your_username'
proxy_pass = 'your_password'
# ایجاد کلاس پروکسی با احراز هویت
proxy_class = Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass)
uri = URI('https://httpbin.org/ip')
proxy_class.start(uri.host, uri.port, use_ssl: true) do |http|
# غیرفعال کردن تأیید SSL (فقط برای تست!)
# http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri)
request['User-Agent'] = 'Mozilla/5.0 (compatible; MyBot/1.0)'
response = http.request(request)
puts "IP: #{response.body}"
puts "Status: #{response.code}"
end
نکته مهم: هنگام استفاده از پروکسی HTTPS (تونلسازی از طریق CONNECT) Net::HTTP به طور خودکار یک اتصال SSL با سرور هدف از طریق تونل پروکسی برقرار میکند. این روش برای بیشتر پروکسیها به درستی کار میکند.
تنظیم از طریق متغیرهای محیطی. یک روش خوب این است که دادههای پروکسی را در کد هاردکد نکنید، بلکه آنها را از متغیرهای محیطی بخوانید:
require 'net/http'
require 'uri'
# خواندن تنظیمات پروکسی از ENV
proxy_uri = URI(ENV.fetch('HTTP_PROXY', 'http://proxy.example.com:8080'))
proxy_class = Net::HTTP::Proxy(
proxy_uri.host,
proxy_uri.port,
proxy_uri.user,
proxy_uri.password
)
target_uri = URI('https://httpbin.org/ip')
proxy_class.start(target_uri.host, target_uri.port, use_ssl: true) do |http|
response = http.get(target_uri.path)
puts response.body
end
متغیر محیطی را میتوان به صورت HTTP_PROXY=http://user:[email protected]:8080 تنظیم کرد. این روش اجازه میدهد تا پروکسی را بدون تغییر کد تغییر دهید — کافی است متغیر را در فایل .env یا در تنظیمات سرور بهروزرسانی کنید.
اتصال پروکسی از طریق Faraday
Faraday — یکی از محبوبترین HTTP-clientها در اکوسیستم Ruby است. این کتابخانه در بسیاری از برنامههای Rails به دلیل رویکرد راحت middleware و پشتیبانی از آداپتورهای مختلف (Net::HTTP، HTTParty، Typhoeus و غیره) استفاده میشود. تنظیم پروکسی در Faraday بسته به آداپتور مورد استفاده کمی متفاوت است.
تنظیم پایه پروکسی در Faraday:
require 'faraday'
# ایجاد اتصال Faraday با پروکسی
conn = Faraday.new(url: 'https://httpbin.org') do |faraday|
faraday.proxy = {
uri: 'http://proxy.example.com:8080',
user: 'your_username',
password: 'your_password'
}
faraday.headers['User-Agent'] = 'Mozilla/5.0 (compatible; MyBot/1.0)'
faraday.adapter Faraday.default_adapter
end
response = conn.get('/ip')
puts response.body
puts "Status: #{response.status}"
پارامتر faraday.proxy یک هش با کلیدهای uri، user و password را میپذیرد. همچنین میتوانید یک رشته URI را به طور مستقیم ارسال کنید، اگر پروکسی نیاز به احراز هویت نداشته باشد.
Faraday با آداپتور Net::HTTP و تنظیمات پیشرفته:
require 'faraday'
conn = Faraday.new(url: 'https://httpbin.org') do |faraday|
faraday.proxy = 'http://user:[email protected]:8080'
# تنظیمات تایماوت
faraday.options.timeout = 30
faraday.options.open_timeout = 10
# Middleware برای لاگگذاری (مناسب برای دیباگ)
faraday.response :logger
# تلاش مجدد در صورت بروز خطاهای اتصال
faraday.request :retry, max: 3, interval: 1
# آداپتور
faraday.adapter :net_http
end
begin
response = conn.get('/ip')
puts response.body
rescue Faraday::ConnectionFailed => e
puts "خطای اتصال: #{e.message}"
rescue Faraday::TimeoutError => e
puts "تایماوت: #{e.message}"
end
Middleware :retry به ویژه هنگام کار با پروکسی مفید است — اگر یک آدرس به طور موقت در دسترس نباشد، Faraday به طور خودکار درخواست را تکرار میکند. این برای عملکرد مطمئن اسکریپت در تولید حیاتی است.
Faraday با آداپتور Typhoeus (برای درخواستهای موازی):
# Gemfile: gem 'typhoeus'
require 'faraday'
require 'typhoeus/adapters/faraday'
conn = Faraday.new(url: 'https://httpbin.org') do |faraday|
faraday.proxy = 'http://user:[email protected]:8080'
faraday.adapter :typhoeus
end
# درخواستهای موازی از طریق پروکسی
responses = []
conn.in_parallel do
responses << conn.get('/ip')
responses << conn.get('/headers')
responses << conn.get('/user-agent')
end
responses.each { |r| puts r.body }
چرخش پروکسی: تغییر خودکار IP
یک آدرس پروکسی، حتی اگر مسکونی باشد، دیر یا زود تحت محدودیتها قرار میگیرد هنگام پارس کردن شدید. راهحل — چرخش: تغییر خودکار IP بعد از هر درخواست یا از طریق فواصل مشخص. بیایید یک روتاتور ساده برای اسکریپتهای Ruby پیادهسازی کنیم.
روتاتور ساده بر اساس آرایه پروکسی:
require 'net/http'
require 'uri'
class ProxyRotator
def initialize(proxies)
@proxies = proxies
@index = 0
@mutex = Mutex.new
end
def next_proxy
@mutex.synchronize do
proxy = @proxies[@index % @proxies.length]
@index += 1
proxy
end
end
def random_proxy
@proxies.sample
end
end
# لیست پروکسیها به فرمت [host, port, user, pass]
proxies = [
['proxy1.example.com', 8080, 'user1', 'pass1'],
['proxy2.example.com', 8080, 'user2', 'pass2'],
['proxy3.example.com', 8080, 'user3', 'pass3'],
]
rotator = ProxyRotator.new(proxies)
# پارس کردن لیست URL از طریق پروکسیهای مختلف
urls = [
'https://httpbin.org/ip',
'https://httpbin.org/headers',
'https://httpbin.org/user-agent'
]
urls.each do |url|
proxy = rotator.next_proxy
proxy_class = Net::HTTP::Proxy(proxy[0], proxy[1], proxy[2], proxy[3])
uri = URI(url)
begin
proxy_class.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.read_timeout = 15
response = http.get(uri.path)
puts "#{url} -> Status: #{response.code}, Proxy: #{proxy[0]}"
end
rescue => e
puts "خطا با پروکسی #{proxy[0]}: #{e.message}"
# به طور خودکار به پروکسی بعدی بروید
end
sleep(rand(0.5..2.0)) # تأخیر تصادفی بین درخواستها
end
تأخیر تصادفی بین درخواستها (sleep(rand(0.5..2.0))) — یک عنصر مهم است. الگوی درخواستها با فواصل ثابت به راحتی توسط سیستمهای ضد ربات شناسایی میشود. تأخیرهای تصادفی رفتار کاربر واقعی را شبیهسازی میکنند.
چرخش از طریق Faraday با middleware:
require 'faraday'
class ProxyMiddleware < Faraday::Middleware
PROXIES = [
'http://user1:[email protected]:8080',
'http://user2:[email protected]:8080',
'http://user3:[email protected]:8080',
].freeze
def call(env)
# انتخاب یک پروکسی تصادفی برای هر درخواست
proxy_uri = URI(PROXIES.sample)
env[:request][:proxy] = {
uri: proxy_uri,
user: proxy_uri.user,
password: proxy_uri.password
}
@app.call(env)
end
end
# ثبت middleware
Faraday::Middleware.register_middleware proxy_rotator: ProxyMiddleware
conn = Faraday.new(url: 'https://httpbin.org') do |faraday|
faraday.use :proxy_rotator
faraday.adapter :net_http
end
5.times do
response = conn.get('/ip')
puts response.body
end
ادغام پروکسی در برنامه Rails
در برنامه Rails، پروکسی بیشتر برای درخواستهای HTTP خارجی نیاز است: ادغام با API، وظایف پسزمینه پارس یا وبهوکها. چند الگوی عملی را بررسی کنیم.
الگوی 1: شیء سرویس با Faraday. یک کلاس سرویس پایه ایجاد کنید که تمام درخواستهای HTTP خارجی را از طریق پروکسی انجام میدهد:
# app/services/http_client.rb
class HttpClient
def self.connection(base_url)
Faraday.new(url: base_url) do |faraday|
# پروکسی از متغیرهای محیطی Rails
if Rails.env.production? && ENV['PROXY_URL'].present?
faraday.proxy = ENV['PROXY_URL']
end
faraday.headers['User-Agent'] = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
faraday.options.timeout = 30
faraday.options.open_timeout = 10
faraday.request :retry, max: 3, interval: 2,
exceptions: [Faraday::ConnectionFailed, Faraday::TimeoutError]
faraday.response :raise_error
faraday.adapter :net_http
end
end
end
# استفاده در کنترلر یا سرویس:
# client = HttpClient.connection('https://api.example.com')
# response = client.get('/products', { category: 'electronics' })
الگوی 2: تنظیم از طریق credentials Rails. برای ذخیره دادههای پروکسی از credentials رمزگذاری شده Rails استفاده کنید:
# config/credentials.yml.enc (از طریق rails credentials:edit ویرایش میشود)
# proxy:
# host: proxy.example.com
# port: 8080
# username: your_user
# password: your_pass
# app/services/proxy_service.rb
class ProxyService
def self.faraday_proxy_config
creds = Rails.application.credentials.proxy
return nil unless creds
{
uri: "http://#{creds[:host]}:#{creds[:port]}",
user: creds[:username],
password: creds[:password]
}
end
def self.net_http_proxy
creds = Rails.application.credentials.proxy
return Net::HTTP::Proxy(nil, nil) unless creds
Net::HTTP::Proxy(
creds[:host],
creds[:port],
creds[:username],
creds[:password]
)
end
end
الگوی 3: وظایف پسزمینه با Sidekiq. اگر پارس کردن یا درخواستهای API در کارگران پسزمینه انجام میشود، تنظیم پروکسی همانطور که هست باقی میماند، اما مهم است که رقابت را در نظر بگیرید:
# app/workers/price_parser_worker.rb
class PriceParserWorker
include Sidekiq::Worker
sidekiq_options retry: 3, queue: :parsers
def perform(product_url)
# ایجاد یک اتصال جدید برای هر کارگر
proxy = ProxyService.net_http_proxy
uri = URI(product_url)
proxy.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.read_timeout = 20
request = Net::HTTP::Get.new(uri)
request['User-Agent'] = random_user_agent
response = http.request(request)
if response.code == '200'
parse_and_save(response.body, product_url)
else
Rails.logger.warn "وضعیت غیرمنتظره #{response.code} برای #{product_url}"
end
end
rescue Net::OpenTimeout, Net::ReadTimeout => e
Rails.logger.error "تایماوت برای #{product_url}: #{e.message}"
raise # Sidekiq وظیفه را تکرار خواهد کرد
end
private
def random_user_agent
agents = [
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36'
]
agents.sample
end
def parse_and_save(html, url)
# منطق پارس کردن...
end
end
مدیریت خطاها و تایماوتها
کار کردن از طریق پروکسی یک لایه اضافی اضافه میکند که میتواند خطاهای خاصی تولید کند. مدیریت درست استثناها تفاوت بین یک اسکریپت است که بعد از 5 دقیقه سقوط میکند و یک اسکریپت است که ساعتها بدون مداخله کار میکند.
انواع اصلی خطاها هنگام کار با پروکسی در Ruby:
| استثنا | دلیل | چه کار کنیم |
|---|---|---|
Net::OpenTimeout |
پروکسی پاسخ نمیدهد | پروکسی را تغییر دهید، تکرار کنید |
Net::ReadTimeout |
پروکسی کند است یا وبسایت پاسخ نمیدهد | تایماوت را افزایش دهید یا پروکسی را تغییر دهید |
Errno::ECONNREFUSED |
پروکسی سرور اتصال را رد کرد | دادههای پروکسی را بررسی کنید |
OpenSSL::SSL::SSLError |
مشکل با SSL از طریق پروکسی | تنظیمات SSL را بررسی کنید |
| HTTP 407 | نام کاربری/رمز عبور نادرست پروکسی | مدارک را بررسی کنید |
| HTTP 403/429 | IP توسط وبسایت مسدود شده است | پروکسی را تغییر دهید، یک وقفه اضافه کنید |
مدیریت جامع خطاها با تغییر خودکار پروکسی:
require 'net/http'
require 'uri'
class RobustHttpClient
MAX_RETRIES = 3
RETRIABLE_ERRORS = [
Net::OpenTimeout,
Net::ReadTimeout,
Errno::ECONNREFUSED,
Errno::ECONNRESET,
OpenSSL::SSL::SSLError
].freeze
def initialize(proxies)
@proxies = proxies.dup
@failed_proxies = []
end
def get(url, retries: MAX_RETRIES)
uri = URI(url)
attempt = 0
begin
attempt += 1
proxy = current_proxy
proxy_class = Net::HTTP::Proxy(*proxy)
proxy_class.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
http.open_timeout = 10
http.read_timeout = 20
request = Net::HTTP::Get.new(uri)
request['User-Agent'] = 'Mozilla/5.0 (compatible; RubyBot/1.0)'
response = http.request(request)
case response.code.to_i
when 200..299
response
when 407
raise "احراز هویت پروکسی برای #{proxy[0]} ناموفق بود"
when 403, 429
rotate_proxy!
raise "IP مسدود شده (#{response.code})، چرخش پروکسی"
else
raise "وضعیت HTTP غیرمنتظره: #{response.code}"
end
end
rescue *RETRIABLE_ERRORS => e
Rails.logger.warn "خطای اتصال (تلاش #{attempt}/#{retries}): #{e.message}"
rotate_proxy!
retry if attempt < retries
raise "پس از #{retries} تلاش ناموفق: #{e.message}"
rescue RuntimeError => e
Rails.logger.warn "خطای HTTP (تلاش #{attempt}/#{retries}): #{e.message}"
retry if attempt < retries
raise
end
end
private
def current_proxy
@proxies.first || raise("هیچ پروکسی در دسترس نیست!")
end
def rotate_proxy!
failed = @proxies.shift
@failed_proxies << failed
Rails.logger.info "پروکسی چرخش یافت. باقیمانده: #{@proxies.length}"
end
end
پروکسی SOCKS5 در Ruby: تنظیم از طریق socksify
Net::HTTP به طور بومی از SOCKS5 پشتیبانی نمیکند — فقط پروکسیهای HTTP/HTTPS. برای کار با SOCKS5 به یک کتابخانه اضافی نیاز است. محبوبترین گزینه — جواهر socksify است.
چرا SOCKS5 ممکن است بر HTTP-proxy ترجیح داده شود؟ پروتکل SOCKS5 در سطح پایینتری کار میکند — هر ترافیک TCP را پروکسی میکند، نه فقط HTTP. علاوه بر این، SOCKS5 از احراز هویت پشتیبانی میکند و متادادههای کمتری درباره درخواست را منتقل میکند، که آن را کمتر قابل شناسایی برای سیستمهای شناسایی رباتها میکند.
# Gemfile
# gem 'socksify'
require 'socksify'
require 'socksify/http'
require 'net/http'
require 'uri'
# تنظیمات جهانی پروکسی SOCKS5
TCPSocket::socks_server = 'proxy.example.com'
TCPSocket::socks_port = 1080
# اختیاری: احراز هویت (نام کاربری/رمز عبور SOCKS5)
# TCPSocket::socks_username = 'your_user'
# TCPSocket::socks_password = 'your_pass'
# حالا تمام درخواستهای Net::HTTP از طریق SOCKS5 میروند
uri = URI('https://httpbin.org/ip')
response = Net::HTTP.get_response(uri)
puts response.body
توجه داشته باشید: هنگام استفاده از socksify تنظیمات به طور جهانی برای تمام اتصالات TCP در فرآیند اعمال میشود. اگر به تنظیمات انعطافپذیرتری نیاز دارید — از Net::HTTP.SOCKSProxy از همان جواهر استفاده کنید:
require 'socksify/http'
# ایجاد کلاس پروکسی SOCKS5 (مشابه Net::HTTP::Proxy برای HTTP)
socks_proxy = Net::HTTP.SOCKSProxy('proxy.example.com', 1080)
uri = URI('https://httpbin.org/ip')
socks_proxy.start(uri.host, uri.port, use_ssl: true) do |http|
response = http.get(uri.path)
puts response.body
end
برای Faraday با SOCKS5 به یک آداپتور نیاز دارید که از این پروتکل پشتیبانی کند. گزینه خوبی faraday-net_http در ترکیب با socksify است، یا استفاده از آداپتور مبتنی بر curl faraday-typhoeus که به طور بومی از SOCKS5 از طریق libcurl پشتیبانی میکند.
💡 نکتهای در مورد انتخاب پروتکل
برای بیشتر وظایف پارس کردن و کار با API، پروکسیهای HTTP/HTTPS کافی هستند — آنها در تنظیمات سادهتر و به طور بومی پشتیبانی میشوند. SOCKS5 باید زمانی استفاده شود که شما نیاز به پروکسی کردن نه تنها ترافیک HTTP دارید، یا زمانی که پروکسیهای HTTP به راحتی توسط سرویس هدف شناسایی میشوند. پروکسیهای موبایل و مسکونی در هر دو پروتکل در دسترس هستند.
نتیجهگیری و توصیهها
تنظیم پروکسی در Ruby نیاز به کتابخانههای پیچیده ندارد — Net::HTTP به طور پیشفرض از پروکسیهای HTTP پشتیبانی میکند، و Faraday ادغام را به دلیل معماری middleware حتی راحتتر میکند. نکات کلیدی این راهنما:
- برای Net::HTTP از
Net::HTTP::Proxyاستفاده کنید — این یک روش داخلی و قابل اعتماد است. - برای Faraday، پارامتر
faraday.proxyیک رشته URI یا هش با مدارک را میپذیرد. - دادههای پروکسی را در متغیرهای محیطی یا credentials Rails ذخیره کنید — در کد هاردکد نکنید.
- چرخش پروکسی و مدیریت خطاها را برای عملکرد مطمئن در تولید پیادهسازی کنید.
- تأخیرهای تصادفی و چرخش User-Agent را برای شبیهسازی رفتار انسانی اضافه کنید.
- برای SOCKS5 از جواهر
socksifyاستفاده کنید.
انتخاب نوع پروکسی به وظیفه بستگی دارد. اگر شما یک پارسر برای Wildberries یا Ozon مینویسید — پروکسیهای مسکونی بهترین تعادل بین سرعت و دور زدن حفاظتها را فراهم میکنند: IPهای واقعی کاربران خانگی به ندرت در لیستهای مسدود قرار میگیرند. برای وظایف با بار بالا و حجم بالای درخواستها به منابع کمتر محافظتشده، پروکسیهای دیتاسنتر مناسبتر هستند — آنها سریعتر و ارزانتر در محاسبه بر اساس درخواست هستند. اگر اسکریپت Ruby شما با شبکههای اجتماعی یا APIهای تبلیغاتی کار میکند — به پروکسیهای موبایل توجه کنید: آدرسهای IP آنها بالاترین سطح اعتماد را در بیشتر پلتفرمها دارند.
```