यदि आप एक पार्सर लिख रहे हैं, बाहरी API का एकीकरण कर रहे हैं या Ruby पर डेटा संग्रहण को स्वचालित कर रहे हैं - निस्संदेह आप IP द्वारा ब्लॉकिंग का सामना करेंगे। Wildberries, Ozon, Instagram और दर्जनों अन्य सेवाएँ एक ही पते से कई सौ अनुरोधों के बाद अनुरोधों को काट देती हैं। समाधान एक ही है - प्रॉक्सी। इस लेख में, हम देखेंगे कि कैसे Ruby प्रोजेक्ट में मानक Net::HTTP और लोकप्रिय HTTP क्लाइंट Faraday के माध्यम से प्रॉक्सी को जोड़ना है, IP रोटेशन सेट करना है और त्रुटियों को सही तरीके से संभालना है - चाहे वह Rails एप्लिकेशन में हो या साधारण स्क्रिप्ट में।
Ruby डेवलपर के लिए प्रॉक्सी: मुख्य परिदृश्य
Ruby का उपयोग उन कार्यों के लिए किया जाता है जहाँ प्रॉक्सी के बिना काम नहीं चल सकता। कोड पर जाने से पहले, यह समझना महत्वपूर्ण है कि उन्हें किन स्थितियों में आवश्यकता होती है - यह सही प्रकार और समाधान की वास्तुकला चुनने में मदद करेगा।
पार्सिंग और डेटा संग्रहण। यह सबसे सामान्य परिदृश्य है। आप Ruby में एक स्क्रिप्ट लिखते हैं जो Wildberries, Ozon या Avito के पृष्ठों को बायपास करती है, कीमतें और उत्पादों की विशेषताएँ इकट्ठा करती है। बिना प्रॉक्सी के, ऐसी स्क्रिप्ट को कुछ ही मिनटों में IP द्वारा ब्लॉक कर दिया जाएगा। वेबसाइटें एक ही पते से सैकड़ों अनुरोध देखती हैं और स्वचालित रूप से सुरक्षा सक्रिय कर देती हैं - कैप्चा, अस्थायी बैन या पूर्ण सेवा से इनकार।
भौगोलिक रूप से निर्भर 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 को पार्स करती है या सुरक्षित वेबसाइटों के साथ काम करती है - यह एक आदर्श विकल्प है। वेबसाइटें एक सामान्य उपयोगकर्ता को देखती हैं, न कि सर्वर।
मोबाइल प्रॉक्सी मोबाइल ऑपरेटरों (4G/5G) के IP के माध्यम से काम करती हैं। ये प्लेटफार्मों के दृष्टिकोण से सबसे विश्वसनीय पते हैं - एक मोबाइल IP का उपयोग सैकड़ों वास्तविक उपयोगकर्ता एक साथ कर सकते हैं, इसलिए इसके द्वारा ब्लॉक होना अत्यंत दुर्लभ है। यदि आपकी Ruby स्क्रिप्ट सोशल नेटवर्क या विज्ञापन प्लेटफार्मों के साथ काम करती है - मोबाइल प्रॉक्सी ब्लॉक होने के जोखिम को न्यूनतम तक कम कर देगी।
Net::HTTP में प्रॉक्सी: बुनियादी सेटअप
Net::HTTP - HTTP अनुरोधों के लिए Ruby की मानक लाइब्रेरी है, जो भाषा के मानक वितरण में शामिल है। यह विशेष विधि 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 ऑब्जेक्ट को एक ही होस्ट के लिए कई अनुरोधों के लिए पुन: उपयोग करने की आवश्यकता होती है। ध्यान दें: प्रॉक्सी पैरामीटर तीसरे और चौथे तर्क के रूप में पास किए जाते हैं, न कि अलग विधि के माध्यम से।
Net::HTTP के माध्यम से प्रमाणीकरण और HTTPS
अधिकांश वाणिज्यिक प्रॉक्सी प्रमाणीकरण की आवश्यकता होती है - लॉगिन और पासवर्ड। इसके अलावा, 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
पर्यावरण चर के माध्यम से सेटिंग। एक अच्छी प्रथा यह है कि प्रॉक्सी डेटा को कोड में हार्डकोड करने के बजाय, उन्हें पर्यावरण चर से पढ़ें:
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 Ruby पारिस्थितिकी तंत्र में सबसे लोकप्रिय HTTP क्लाइंट में से एक है। इसका उपयोग कई Rails एप्लिकेशनों में किया जाता है, जो सुविधाजनक मिडलवेयर दृष्टिकोण और विभिन्न एडेप्टर (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 स्ट्रिंग भी पास कर सकते हैं।
Net::HTTP के साथ Faraday और विस्तारित सेटिंग्स:
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
# लॉगिंग के लिए मिडलवेयर (डीबगिंग के लिए सुविधाजनक)
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
मिडलवेयर :retry प्रॉक्सी के साथ काम करते समय विशेष रूप से उपयोगी है - यदि एक पता अस्थायी रूप से अनुपलब्ध है, तो Faraday स्वचालित रूप से अनुरोध को दोहराएगा। यह उत्पादन में स्क्रिप्ट के विश्वसनीय संचालन के लिए महत्वपूर्ण है।
Typhoeus एडेप्टर के साथ Faraday (समानांतर अनुरोधों के लिए):
# 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 के माध्यम से रोटेशन:
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
# मिडलवेयर पंजीकरण
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: Rails क्रेडेंशियल्स के माध्यम से सेटिंग। प्रॉक्सी डेटा को स्टोर करने के लिए 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
Ruby में SOCKS5 प्रॉक्सी: socksify के माध्यम से सेटअप
मानक Net::HTTP SOCKS5 का स्वदेशी समर्थन नहीं करता है - केवल HTTP/HTTPS प्रॉक्सी। SOCKS5 के साथ काम करने के लिए एक अतिरिक्त पुस्तकालय की आवश्यकता होती है। सबसे लोकप्रिय विकल्प - जेम socksify।
SOCKS5 को HTTP प्रॉक्सी पर प्राथमिकता क्यों दी जा सकती है? 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 प्रॉक्सी क्लास बनाना (HTTP के लिए Net::HTTP::Proxy के समान)
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
SOCKS5 के लिए Faraday के साथ एक एडेप्टर की आवश्यकता होगी जो इस प्रोटोकॉल का समर्थन करता हो। एक अच्छा विकल्प faraday-net_http है जो socksify के साथ जोड़ा गया है, या faraday-typhoeus का उपयोग करना, जो libcurl के माध्यम से SOCKS5 का स्वदेशी समर्थन करता है।
💡 प्रोटोकॉल चुनने के लिए सुझाव
अधिकांश पार्सिंग कार्यों और API के साथ काम करने के लिए HTTP/HTTPS प्रॉक्सी पर्याप्त हैं - ये सेटअप में सरल हैं और स्वदेशी रूप से समर्थित हैं। SOCKS5 का उपयोग तब करें जब आपको केवल HTTP ट्रैफ़िक को प्रॉक्सी करने की आवश्यकता हो, या जब HTTP प्रॉक्सी को लक्षित सेवा द्वारा आसानी से पहचाना जाता हो। मोबाइल और रिहायशी प्रॉक्सी दोनों प्रोटोकॉल में उपलब्ध हैं।
निष्कर्ष और सिफारिशें
Ruby में प्रॉक्सी सेटअप के लिए जटिल पुस्तकालयों की आवश्यकता नहीं होती - मानक Net::HTTP HTTP प्रॉक्सी का स्वदेशी समर्थन करता है, और Faraday मिडलवेयर आर्किटेक्चर के कारण एकीकरण को और अधिक सुविधाजनक बनाता है। इस गाइड से मुख्य निष्कर्ष:
- Net::HTTP के लिए
Net::HTTP::Proxyका उपयोग करें - यह एक अंतर्निहित और विश्वसनीय तरीका है। - Faraday के लिए पैरामीटर
faraday.proxyURI स्ट्रिंग या क्रेडेंशियल्स के साथ हैश लेता है। - प्रॉक्सी डेटा को पर्यावरण चर या Rails क्रेडेंशियल्स में स्टोर करें - कोड में हार्डकोड न करें।
- उत्पादन में विश्वसनीय संचालन के लिए प्रॉक्सी रोटेशन और त्रुटि प्रबंधन लागू करें।
- यादृच्छिक देरी और User-Agent का रोटेशन जोड़ें ताकि मानव व्यवहार का अनुकरण किया जा सके।
- SOCKS5 के लिए
socksifyका उपयोग करें।
प्रॉक्सी के प्रकार का चयन कार्य पर निर्भर करता है। यदि आप Wildberries या Ozon के लिए पार्सर लिख रहे हैं - रिहायशी प्रॉक्सी गति और सुरक्षा को बायपास करने के बीच सबसे अच्छा संतुलन प्रदान करेंगी: वास्तविक घरेलू उपयोगकर्ताओं के IP बहुत कम ही ब्लॉक लिस्ट में आते हैं। उच्च-लोड कार्यों के लिए, जो कम सुरक्षित स्रोतों पर बड़े पैमाने पर अनुरोध करते हैं, डेटा सेंटर प्रॉक्सी उपयुक्त हैं - ये अनुरोध के लिए तेज़ और सस्ते हैं। यदि आपकी Ruby स्क्रिप्ट सोशल नेटवर्क या विज्ञापन API के साथ काम करती है - मोबाइल प्रॉक्सी पर विचार करें: उनके IP पते अधिकांश प्लेटफार्मों पर अधिकतम स्तर की विश्वसनीयता रखते हैं।
```