Scrapy — वेब स्क्रैपिंग के लिए सबसे शक्तिशाली Python ढांचों में से एक है, लेकिन प्रॉक्सी की सही सेटिंग के बिना आपके पार्सर्स कुछ ही मिनटों में ब्लॉक हो जाएंगे। इस गाइड में, मैं Scrapy में प्रॉक्सी को एकीकृत करने के सभी तरीकों को दिखाऊंगा: सबसे सरल सेटअप से लेकर स्वचालित त्रुटि हैंडलिंग के साथ IP पते के उन्नत रोटेशन विधियों तक।
सामग्री बड़े ई-कॉमर्स प्लेटफार्मों और सुरक्षित वेबसाइटों को पार्स करने के वास्तविक अनुभव पर आधारित है। आप तैयार कोड के उदाहरण प्राप्त करेंगे, जिन्हें आप तुरंत अपने प्रोजेक्ट में उपयोग कर सकते हैं।
क्यों Scrapy बिना प्रॉक्सी के ब्लॉक होता है
आधुनिक वेबसाइटें पार्सिंग से बचने के लिए कई स्तरों की सुरक्षा का उपयोग करती हैं। भले ही आपने User-Agent और अनुरोधों के बीच देरी सेट की हो, आपका IP पता कई संकेतों के माध्यम से स्वचालन का संकेत देता है:
- अनुरोधों की आवृत्ति: एक IP एक मिनट में 100+ अनुरोध करता है — यह बॉट का स्पष्ट संकेत है
- व्यवहार के पैटर्न: बिना यादृच्छिक संक्रमण के पृष्ठों का अनुक्रमिक दौरा
- JavaScript की अनुपस्थिति: Scrapy JS को निष्पादित नहीं करता है, जो आसानी से पता लगाया जा सकता है
- भौगोलिक स्थान: घरेलू नेटवर्क के बजाय डेटा सेंटर से पहुंच
परिणाम — कुछ घंटों या दिनों के लिए IP पर बैन। विशेष रूप से आक्रामक सुरक्षा का उपयोग मार्केटप्लेस (Amazon, Wildberries, Ozon), सामाजिक नेटवर्क और Cloudflare के साथ वेबसाइटों द्वारा किया जाता है। प्रॉक्सी इस समस्या को हल करती हैं, अनुरोधों को कई IP पतों के बीच वितरित करके।
महत्वपूर्ण: प्रॉक्सी के साथ भी दर सीमाओं का पालन करना आवश्यक है। अनुशंसित गति: एक IP पर प्रति सेकंड 1-3 अनुरोध। उच्च गति की पार्सिंग के लिए 50+ प्रॉक्सी के पूल का उपयोग करें।
Scrapy में प्रॉक्सी का बुनियादी सेटअप
सबसे सरल तरीका — प्रॉक्सी को सीधे मकड़ी की सेटिंग में निर्दिष्ट करना। यह विधि परीक्षण या एक प्रॉक्सी सर्वर के साथ छोटे डेटा वॉल्यूम को पार्स करने के लिए उपयुक्त है।
विधि 1: अनुरोध में मेटा के माध्यम से
import scrapy
class MySpider(scrapy.Spider):
name = 'example'
start_urls = ['https://example.com']
def start_requests(self):
proxy = 'http://username:password@proxy.example.com:8080'
for url in self.start_urls:
yield scrapy.Request(
url=url,
callback=self.parse,
meta={'proxy': proxy}
)
def parse(self, response):
# आपकी पार्सिंग लॉजिक
self.log(f'Scraped {response.url} via {response.meta["proxy"]}')
प्रॉक्सी का प्रारूप प्रोटोकॉल और प्रमाणीकरण विधि पर निर्भर करता है:
http://proxy.example.com:8080— बिना प्रमाणीकरणhttp://user:pass@proxy.example.com:8080— लॉगिन/पासवर्ड के साथsocks5://user:pass@proxy.example.com:1080— SOCKS5 प्रॉक्सी
विधि 2: settings.py में वैश्विक सेटिंग
# settings.py
# सभी अनुरोधों के लिए HTTP प्रॉक्सी
HTTPPROXY_ENABLED = True
HTTPPROXY_AUTH_ENCODING = 'utf-8'
# पर्यावरण चर के माध्यम से सेटिंग
HTTP_PROXY = 'http://username:password@proxy.example.com:8080'
HTTPS_PROXY = 'http://username:password@proxy.example.com:8080'
यह विधि त्वरित परीक्षण के लिए सुविधाजनक है, लेकिन उत्पादन के लिए उपयुक्त नहीं है: IP का रोटेशन नहीं है, प्रॉक्सी के गिरने पर पूरा पार्सर रुक जाता है, विभिन्न वेबसाइटों के लिए विभिन्न प्रॉक्सी का उपयोग करना असंभव है।
कस्टम प्रॉक्सी मिडलवेयर बनाना
उत्पादन पार्सिंग के लिए एक कस्टम मिडलवेयर की आवश्यकता होती है, जो प्रॉक्सी के पूल का प्रबंधन करेगा, त्रुटियों को संभालेगा और स्वचालित रूप से IP को रोटेट करेगा। यहाँ एक बुनियादी कार्यान्वयन है:
# middlewares.py
import random
from scrapy import signals
from scrapy.exceptions import NotConfigured
class RandomProxyMiddleware:
def __init__(self, proxy_list):
self.proxy_list = proxy_list
@classmethod
def from_crawler(cls, crawler):
# सेटिंग से प्रॉक्सी की सूची लोड करें
proxy_list = crawler.settings.getlist('PROXY_LIST')
if not proxy_list:
raise NotConfigured('PROXY_LIST not configured')
return cls(proxy_list)
def process_request(self, request, spider):
# पूल से एक यादृच्छिक प्रॉक्सी चुनें
proxy = random.choice(self.proxy_list)
request.meta['proxy'] = proxy
spider.logger.info(f'Using proxy: {proxy}')
def process_exception(self, request, exception, spider):
# त्रुटि पर, एक और प्रॉक्सी आजमाते हैं
proxy = random.choice(self.proxy_list)
request.meta['proxy'] = proxy
spider.logger.warning(
f'Proxy error, switching to: {proxy}'
)
return request
अब settings.py में मिडलवेयर के उपयोग को सेट करें:
# settings.py
# प्रॉक्सी की सूची (फाइल या API से लोड की जा सकती है)
PROXY_LIST = [
'http://user1:pass1@proxy1.example.com:8080',
'http://user2:pass2@proxy2.example.com:8080',
'http://user3:pass3@proxy3.example.com:8080',
# ... प्रभावी रोटेशन के लिए 50+ प्रॉक्सी जोड़ें
]
# मिडलवेयर को कनेक्ट करें
DOWNLOADER_MIDDLEWARES = {
'myproject.middlewares.RandomProxyMiddleware': 350,
'scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware': 400,
}
# त्रुटियों पर पुनः प्रयास
RETRY_TIMES = 3
RETRY_HTTP_CODES = [500, 502, 503, 504, 408, 429]
प्रॉक्सी रोटेशन: तीन कार्यशील विधियाँ
प्रॉक्सी का यादृच्छिक चयन (जैसा कि ऊपर के उदाहरण में) सबसे सरल है, लेकिन सबसे प्रभावी विधि नहीं है। विभिन्न परिदृश्यों के लिए तीन रोटेशन रणनीतियों पर विचार करें।
विधि 1: राउंड-रॉबिन (क्रमिक रोटेशन)
प्रॉक्सी को गोलाकार रूप से चुना जाता है। यह लोड को समान रूप से वितरित करने के लिए उपयुक्त है:
class RoundRobinProxyMiddleware:
def __init__(self, proxy_list):
self.proxy_list = proxy_list
self.current_index = 0
@classmethod
def from_crawler(cls, crawler):
proxy_list = crawler.settings.getlist('PROXY_LIST')
return cls(proxy_list)
def process_request(self, request, spider):
# गोलाकार रूप से अगली प्रॉक्सी लें
proxy = self.proxy_list[self.current_index]
self.current_index = (self.current_index + 1) % len(self.proxy_list)
request.meta['proxy'] = proxy
विधि 2: ब्लैकलिस्ट के साथ स्मार्ट रोटेशन
समस्याग्रस्त प्रॉक्सी को ट्रैक करें और उन्हें अस्थायी रूप से रोटेशन से बाहर करें:
import time
from collections import defaultdict
class SmartProxyMiddleware:
def __init__(self, proxy_list):
self.proxy_list = proxy_list
self.proxy_errors = defaultdict(int)
self.blacklist = set()
self.blacklist_timeout = 300 # 5 मिनट
self.blacklist_time = {}
@classmethod
def from_crawler(cls, crawler):
proxy_list = crawler.settings.getlist('PROXY_LIST')
return cls(proxy_list)
def get_working_proxies(self):
# ब्लैकलिस्ट से उन प्रॉक्सी को हटा दें जिनका टाइमआउट समाप्त हो गया है
current_time = time.time()
expired = [
proxy for proxy, ban_time in self.blacklist_time.items()
if current_time - ban_time > self.blacklist_timeout
]
for proxy in expired:
self.blacklist.discard(proxy)
self.proxy_errors[proxy] = 0
# कार्यशील प्रॉक्सी लौटाएं
return [p for p in self.proxy_list if p not in self.blacklist]
def process_request(self, request, spider):
working_proxies = self.get_working_proxies()
if not working_proxies:
spider.logger.error('सभी प्रॉक्सी ब्लैकलिस्टेड हैं!')
return
proxy = random.choice(working_proxies)
request.meta['proxy'] = proxy
def process_response(self, request, response, spider):
# यदि ब्लॉक मिला — ब्लैकलिस्ट में जोड़ें
if response.status in [403, 429, 503]:
proxy = request.meta.get('proxy')
self.proxy_errors[proxy] += 1
if self.proxy_errors[proxy] >= 3:
self.blacklist.add(proxy)
self.blacklist_time[proxy] = time.time()
spider.logger.warning(
f'Proxy {proxy} को {self.blacklist_timeout}s के लिए ब्लैकलिस्ट किया गया'
)
return response
विधि 3: प्रदाता के API के माध्यम से रोटेशन
कई प्रॉक्सी प्रदाता (जिनमें रिहायशी प्रॉक्सी शामिल हैं) रोटेटिंग एंडपॉइंट प्रदान करते हैं — एक URL, जो हर अनुरोध पर IP को स्वचालित रूप से बदलता है:
# settings.py
# स्वचालित रोटेशन के साथ एकल एंडपॉइंट
ROTATING_PROXY = 'http://username:password@rotating.proxy.com:8080'
# सरल मिडलवेयर
class RotatingProxyMiddleware:
def __init__(self, proxy):
self.proxy = proxy
@classmethod
def from_crawler(cls, crawler):
proxy = crawler.settings.get('ROTATING_PROXY')
return cls(proxy)
def process_request(self, request, spider):
# एक URL, लेकिन प्रत्येक अनुरोध नए IP के साथ होता है
request.meta['proxy'] = self.proxy
यह उत्पादन के लिए सबसे सुविधाजनक विधि है: प्रॉक्सी के पूल का प्रबंधन करने की आवश्यकता नहीं है, प्रदाता स्वयं IP की गुणवत्ता की निगरानी करता है और समस्याग्रस्त को बदलता है। यह विशेष रूप से रिहायशी प्रॉक्सी के साथ प्रभावी है, जहां IP का पूल लाखों पते तक पहुंच सकता है।
प्रमाणीकरण: लॉगिन/पासवर्ड बनाम IP व्हाइटलिस्ट
प्रॉक्सी प्रदाता दो प्रमाणीकरण विधियाँ प्रदान करते हैं। चयन कनेक्शन की गति और सेटिंग की सुविधा को प्रभावित करता है।
यूजर:पास प्रमाणीकरण
लॉगिन और पासवर्ड प्रॉक्सी के URL में भेजे जाते हैं। Scrapy स्वचालित रूप से उन्हें HTTP हेडर Proxy-Authorization में परिवर्तित करता है:
proxy = 'http://username:password@proxy.example.com:8080'
request.meta['proxy'] = proxy
# Scrapy स्वचालित रूप से हेडर जोड़ेगा:
# Proxy-Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
फायदे: किसी भी IP से काम करता है, कोड में प्रॉक्सी को बदलना आसान है।
नुकसान: प्रत्येक अनुरोध पर थोड़ी अधिकता (~50-100ms), कोड में खुले में क्रेडेंशियल।
IP व्हाइटलिस्ट प्रमाणीकरण
आप अपने सर्वर के IP को प्रदाता के व्हाइटलिस्ट में जोड़ते हैं, प्रमाणीकरण की आवश्यकता नहीं होती:
proxy = 'http://proxy.example.com:8080' # बिना लॉगिन/पासवर्ड
request.meta['proxy'] = proxy
फायदे: 50-100ms तेजी, अधिक सुरक्षित (कोड में क्रेडेंशियल नहीं)।
नुकसान: केवल निश्चित IP से काम करता है, सर्वर बदलने पर व्हाइटलिस्ट को अपडेट करना आवश्यक है।
उत्पादन के लिए सिफारिश:
विशेष सर्वरों (AWS, Google Cloud, Hetzner) से पार्सिंग के लिए IP व्हाइटलिस्ट का उपयोग करें। विकास और परीक्षण के लिए स्थानीय मशीन से — यूजर:पास प्रमाणीकरण।
त्रुटियों को संभालना और स्वचालित IP स्विच करना
उच्च गुणवत्ता वाली प्रॉक्सी के साथ भी त्रुटियाँ होंगी: टाइमआउट, कनेक्शन अस्वीकृत, ब्लॉक। त्रुटियों को सही ढंग से संभालना पार्सर के स्थिर संचालन के लिए महत्वपूर्ण है।
HTTP स्थिति को संभालना
class ProxyMiddleware:
def process_response(self, request, response, spider):
# कोड, जिन पर प्रॉक्सी बदलने और पुनः प्रयास करने की आवश्यकता है
ban_codes = [403, 407, 429, 503]
if response.status in ban_codes:
proxy = request.meta.get('proxy')
spider.logger.warning(
f'Got {response.status} from {proxy}, retrying...'
)
# नए प्रॉक्सी के साथ पुनः प्रयास के लिए चिह्नित करें
request.meta['dont_retry'] = False
request.meta['proxy'] = self.get_new_proxy()
return request
return response
नेटवर्क अपवाद को संभालना
from twisted.internet.error import TimeoutError, ConnectionRefusedError
from scrapy.exceptions import IgnoreRequest
class ProxyMiddleware:
def process_exception(self, request, exception, spider):
# प्रॉक्सी से कनेक्शन की त्रुटियाँ
proxy_errors = (
TimeoutError,
ConnectionRefusedError,
ConnectionLost,
)
if isinstance(exception, proxy_errors):
proxy = request.meta.get('proxy')
spider.logger.error(
f'Proxy {proxy} कनेक्शन विफल: {exception}'
)
# प्रॉक्सी बदलें और फिर से प्रयास करें
request.meta['proxy'] = self.get_new_proxy()
return request
# अन्य त्रुटियों के लिए मानक हैंडलिंग का उपयोग करें
return None
सामग्री द्वारा ब्लॉक का पता लगाना
कुछ वेबसाइटें HTTP 200 लौटाती हैं, लेकिन कैप्चा या ब्लॉक पृष्ठ दिखाती हैं:
class ProxyMiddleware:
def process_response(self, request, response, spider):
# सामग्री में ब्लॉक के संकेत
ban_indicators = [
'captcha',
'access denied',
'blocked',
'unusual traffic',
'robot check',
]
body_text = response.text.lower()
if any(indicator in body_text for indicator in ban_indicators):
spider.logger.warning(
f'Ban page detected from {request.meta.get("proxy")}'
)
# प्रॉक्सी बदलें और पुनः प्रयास करें
request.meta['proxy'] = self.get_new_proxy()
return request
return response
Scrapy के लिए कौन सा प्रॉक्सी प्रकार चुनें
प्रॉक्सी के प्रकार का चयन लक्षित वेबसाइट, बजट और आवश्यक पार्सिंग गति पर निर्भर करता है। यहाँ मुख्य विकल्पों की तुलना है:
| प्रॉक्सी का प्रकार | गति | लागत | कब उपयोग करें |
|---|---|---|---|
| डेटा सेंटर प्रॉक्सी | उच्च (50-200ms) | कम ($1-3/IP) | सरल वेबसाइटें बिना सुरक्षा, API, आंतरिक उपकरण |
| रिहायशी प्रॉक्सी | मध्यम (300-800ms) | मध्यम ($5-15/GB) | ई-कॉमर्स, सोशल मीडिया, Cloudflare के साथ वेबसाइटें, भू-लक्षित करना |
| मोबाइल प्रॉक्सी | कम (500-1500ms) | उच्च ($50-150/IP) | मोबाइल एप्लिकेशन, Instagram, TikTok, अधिकतम सुरक्षा |
चुनने के लिए सिफारिशें
मार्केटप्लेस के पार्सिंग के लिए (Amazon, Wildberries, Ozon, AliExpress) — केवल रिहायशी प्रॉक्सी। ये वेबसाइटें डेटा सेंटर को आक्रामक रूप से बैन करती हैं। रोटेशन और भू-लक्षित करने की आवश्यकता है (उदाहरण के लिए, Wildberries के लिए रूसी IP)।
समाचार वेबसाइटों, ब्लॉगों, फोरम के पार्सिंग के लिए — डेटा सेंटर प्रॉक्सी उपयुक्त हैं। सुरक्षा न्यूनतम है, गति और ट्रैफ़िक की कम लागत महत्वपूर्ण है।
Cloudflare के साथ वेबसाइटों के पार्सिंग के लिए — रिहायशी प्रॉक्सी अनिवार्य हैं। डेटा सेंटर Cloudflare को लगभग तुरंत पहचान लेते हैं। JS चुनौतियों को बायपास करने के लिए Scrapy के लिए cloudscraper पुस्तकालय जोड़ें।
Google खोज, SEO उपकरणों के पार्सिंग के लिए — भू-लक्षित रिहायशी प्रॉक्सी। Google विभिन्न देशों और शहरों के लिए विभिन्न परिणाम दिखाता है।
सलाह: परीक्षण के लिए 10 रिहायशी प्रॉक्सी के पूल से शुरू करें। यदि आप ब्लॉक प्राप्त करते हैं — पूल को 50-100 IP तक बढ़ाएं। उच्च गति की पार्सिंग (1000+ अनुरोध/मिनट) के लिए 10,000+ IP के पूल के साथ रोटेटिंग एंडपॉइंट का उपयोग करें।
उन्नत तकनीकें: सत्र और स्टिकी IP
कुछ वेबसाइटों के पार्सिंग के दौरान एक ही IP को पूरे सत्र के दौरान बनाए रखना आवश्यक होता है (प्रमाणीकरण, खरीदारी की टोकरी, बहु-चरण फ़ॉर्म)। Scrapy में स्टिकी सत्रों को लागू करने का तरीका यहाँ है।
एक डोमेन के लिए स्टिकी IP
from urllib.parse import urlparse
class StickyProxyMiddleware:
def __init__(self, proxy_list):
self.proxy_list = proxy_list
# डिक्शनरी: डोमेन -> प्रॉक्सी
self.domain_proxy_map = {}
@classmethod
def from_crawler(cls, crawler):
proxy_list = crawler.settings.getlist('PROXY_LIST')
return cls(proxy_list)
def process_request(self, request, spider):
# URL से डोमेन निकालें
domain = urlparse(request.url).netloc
# यदि इस डोमेन के लिए पहले से प्रॉक्सी है — इसका उपयोग करें
if domain in self.domain_proxy_map:
proxy = self.domain_proxy_map[domain]
else:
# अन्यथा एक नया चुनें और याद रखें
proxy = random.choice(self.proxy_list)
self.domain_proxy_map[domain] = proxy
spider.logger.info(f'Assigned {proxy} to {domain}')
request.meta['proxy'] = proxy
सत्र टाइमआउट के साथ स्टिकी IP
एक अधिक उन्नत विकल्प: प्रॉक्सी को एक निश्चित समय (उदाहरण के लिए, 10 मिनट) के लिए डोमेन से जोड़ा जाता है, फिर बदल दिया जाता है:
import time
from urllib.parse import urlparse
class SessionProxyMiddleware:
def __init__(self, proxy_list, session_timeout=600):
self.proxy_list = proxy_list
self.session_timeout = session_timeout # 10 मिनट
# डिक्शनरी: डोमेन -> (प्रॉक्सी, निर्माण का समय)
self.sessions = {}
@classmethod
def from_crawler(cls, crawler):
proxy_list = crawler.settings.getlist('PROXY_LIST')
timeout = crawler.settings.getint('PROXY_SESSION_TIMEOUT', 600)
return cls(proxy_list, timeout)
def get_proxy_for_domain(self, domain):
current_time = time.time()
# सक्रिय सत्र है या नहीं, यह जांचें
if domain in self.sessions:
proxy, created_at = self.sessions[domain]
# यदि सत्र समाप्त नहीं हुआ है — वही प्रॉक्सी का उपयोग करें
if current_time - created_at < self.session_timeout:
return proxy
# नए प्रॉक्सी के साथ नई सत्र बनाएं
new_proxy = random.choice(self.proxy_list)
self.sessions[domain] = (new_proxy, current_time)
return new_proxy
def process_request(self, request, spider):
domain = urlparse(request.url).netloc
proxy = self.get_proxy_for_domain(domain)
request.meta['proxy'] = proxy
कुकी मिडलवेयर के साथ एकीकरण
पूर्ण सत्रों के लिए प्रॉक्सी और कुकीज़ को समन्वयित करना आवश्यक है। Scrapy कुकीज़ को प्रत्येक डोमेन के लिए अलग से संग्रहीत करता है, लेकिन प्रॉक्सी बदलने पर कुकीज़ को साफ करना आवश्यक है:
# settings.py
# कुकी मिडलवेयर सक्षम करें
COOKIES_ENABLED = True
COOKIES_DEBUG = False
# प्रॉक्सी और कुकीज़ को समन्वयित करने के लिए मिडलवेयर
class ProxyCookieMiddleware:
def process_request(self, request, spider):
# वर्तमान प्रॉक्सी प्राप्त करें
current_proxy = request.meta.get('proxy')
# यदि प्रॉक्सी बदल गई है — कुकीज़ साफ करें
previous_proxy = request.meta.get('previous_proxy')
if previous_proxy and previous_proxy != current_proxy:
# इस डोमेन के लिए कुकीज़ साफ करें
jar = spider.crawler.engine.downloader.middleware.middlewares[0].jars
domain = urlparse(request.url).netloc
if domain in jar:
jar[domain].clear()
spider.logger.info(f'Cleared cookies for {domain}')
request.meta['previous_proxy'] = current_proxy
निष्कर्ष
Scrapy में प्रॉक्सी की सही सेटिंग स्थिर पार्सिंग के लिए आधार है बिना ब्लॉक के। हमने सभी प्रमुख पहलुओं पर विचार किया: बुनियादी एकीकरण से लेकर रोटेशन और सत्र प्रबंधन की उन्नत तकनीकों तक।
मुख्य निष्कर्ष:
- उत्पादन के लिए कस्टम मिडलवेयर का उपयोग करें जिसमें स्मार्ट रोटेशन और समस्याग्रस्त IP की ब्लैकलिस्ट हो
- HTTP स्थिति, नेटवर्क अपवाद, सामग्री द्वारा ब्लॉक के सभी प्रकार की त्रुटियों को संभालें
- कार्य के लिए प्रॉक्सी का प्रकार चुनें: सरल वेबसाइटों के लिए डेटा सेंटर, सुरक्षित के लिए रिहायशी
- प्रमाणीकरण वाली वेबसाइटों के लिए स्टिकी सत्रों का उपयोग करें, डोमेन के लिए प्रॉक्सी को बांधें
- 10-50 प्रॉक्सी के पूल से शुरू करें, लोड बढ़ने पर स्केल करें
यदि आप सुरक्षित वेबसाइटों (मार्केटप्लेस, सोशल नेटवर्क, Cloudflare के साथ वेबसाइटें) को पार्स करने की योजना बना रहे हैं, तो मैं रिहायशी प्रॉक्सी का उपयोग करने की सिफारिश करता हूं — वे अधिकतम गुमनामी और न्यूनतम ब्लॉकिंग जोखिम प्रदान करते हैं। उच्च गति की पार्सिंग के लिए रोटेटिंग एंडपॉइंट और 10,000 IP के पूल वाले प्रदाताओं का चयन करें।
इस लेख के सभी कोड के उदाहरण Scrapy 2.x पर परीक्षण किए गए हैं और उत्पादन में उपयोग के लिए तैयार हैं। उन्हें अपने कार्यों के अनुसार अनुकूलित करें और परियोजना के विकास के साथ स्केल करें।