Socks5Proxy

Scrapy प्रॉक्सी सेटअप, मेटा प्रॉक्सी का उपयोग करके प्रत्येक रिक्वेस्ट के लिए अलग IP

यह गाइड Scrapy में Socks5Proxy के HTTP प्रॉक्सी को meta proxy से कनेक्ट करने का तरीका, API से प्राप्त लिस्ट को प्रति-रिक्वेस्ट रोटेट करने वाला डाउनलोडर मिडलवेयर, और टारगेट साइट के अनुसार स्पीड सेटिंग्स समझाती है।

Scrapy प्रॉक्सी को कैसे हैंडल करता है?

Scrapy में डिफॉल्ट रूप से HttpProxyMiddleware ऑन होता है। अगर आप रिक्वेस्ट के मेटा डिक्शनरी में proxy की के तहत एड्रेस डालते हैं, तो वह रिक्वेस्ट उस प्रॉक्सी के माध्यम से जाएगी, और एड्रेस में दिए गए यूजरनेम और पासवर्ड को मिडलवेयर Proxy-Authorization हेडर में बदल देगा। HTTPS एड्रेस CONNECT टनल के माध्यम से जाते हैं।

Scrapy का डिफॉल्ट डाउनलोड हैंडलर HTTP प्रॉक्सी को सपोर्ट करता है। अगर SOCKS5 की सख्त जरूरत है, तो अलग हैंडलर की आवश्यकता होगी, इसलिए Scrapy में एक ही IP के HTTP पोर्ट का उपयोग करने की सलाह दी जाती है। टारगेट साइट पर दिखने वाला IP वही होगा।

उदाहरण में IP 198.51.100.23, HTTP पोर्ट 8000, यूजरनेम spx_user, पासवर्ड spx_pass का उपयोग किया गया है।

pip install scrapy
scrapy startproject shop
cd shop

एक अनुरोध में प्रॉक्सी कैसे जोड़ें?

start_requests में Request बनाते समय meta में proxy डालें। कॉलबैक में अगले पृष्ठ का अनुरोध करते समय भी उसी तरह डालें। एक ही सत्र जारी रखना हो तो पिछली प्रतिक्रिया के meta से proxy मान पास करें तो एक ही IP बना रहेगा।

import scrapy

PROXY = "http://spx_user:spx_pass@198.51.100.23:8000"

class IpCheckSpider(scrapy.Spider):
    name = "ip_check"

    def start_requests(self):
        yield scrapy.Request("https://api.ipify.org?format=json", meta={"proxy": PROXY})

    def parse(self, response):
        self.logger.info("seen as %s", response.json()["ip"])

प्रत्येक अनुरोध के लिए IP को कैसे रोटेट करें?

एक डाउनलोडर मिडलवेयर बनाएं जो सभी अनुरोधों में अगला प्रॉक्सी डाले, ताकि स्पाइडर कोड बदले बिना रोटेशन किया जा सके। नीचे दिया गया मिडलवेयर शुरू होने पर API से सूची प्राप्त करता है और यदि मेटा में पहले से प्रॉक्सी है तो उसे वैसे ही छोड़ देता है, जिससे सेशन स्टिकीनेस और रोटेशन दोनों का एक साथ उपयोग किया जा सके।

API कुंजी को settings.py में रखें या पर्यावरण चर से पढ़ें। क्रम मूल HttpProxyMiddleware(750) से पहले होना चाहिए ताकि मिडलवेयर द्वारा डाला गया पता मूल मिडलवेयर द्वारा संसाधित हो।

import itertools
import requests

class RotatingProxyMiddleware:
    def __init__(self, key):
        text = requests.get(
            "https://socks5proxy.io/api/v1/proxies/download",
            params={"format": "user:pass@ip:port", "protocol": "http"},
            headers={"Authorization": "Bearer " + key},
            timeout=30,
        ).text
        self.pool = itertools.cycle(["http://" + l.strip() for l in text.splitlines() if l.strip()])

    @classmethod
    def from_crawler(cls, crawler):
        return cls(crawler.settings.get("SPX_API_KEY"))

    def process_request(self, request, spider):
        if "proxy" not in request.meta:  # keep a proxy that was set on purpose (sticky sessions)
            request.meta["proxy"] = next(self.pool)

गति और पुनः प्रयास कैसे सेट करें?

CONCURRENT_REQUESTS_PER_DOMAIN एक ही डोमेन पर एक साथ भेजे जाने वाले अनुरोधों की संख्या है। प्रॉक्सी IP जितने अधिक होंगे, इस मान को बढ़ाने पर भी एक IP पर बोझ वही रहता है। उदाहरण के लिए, 500 IP से 50 अनुरोध एक साथ भेजने पर एक IP औसतन 10 अनुरोधों में केवल एक बार उपयोग होता है।

AUTOTHROTTLE चालू करने पर प्रतिक्रिया गति के अनुसार अनुरोध अंतराल स्वचालित रूप से समायोजित होता है। 429 प्रतिक्रिया बढ़ने पर RETRY_HTTP_CODES से पुनः प्रयास करें, लेकिन पुनः प्रयास करते समय मिडलवेयर द्वारा अगला प्रॉक्सी डालने के लिए meta का proxy हटाने का तरीका भी है।

यदि आप चाहते हैं कि एकत्रित किए गए परिणाम पुष्टि पृष्ठ नहीं बल्कि वास्तविक पृष्ठ हों, तो पाइपलाइन में जांच का चरण जोड़ें, जिससे डेटा की गुणवत्ता बेहतर होगी। यदि प्रतिक्रिया में आवश्यक तत्व नहीं हैं, तो इसे किसी अन्य IP से फिर से अनुरोध करने के लिए सेट करें।

  • IP की संख्या के अनुसार डोमेन के अनुसार एक साथ रिक्वेस्ट की संख्या एडजस्ट करें
  • AUTOTHROTTLE से प्रतिक्रिया गति के अनुसार अंतराल
  • 429 और 5xx अन्य IP से पुनः प्रयास करें
  • रिस्पॉन्स कंटेंट चेक करके कैप्चा स्क्रीन फिल्टर करें

IP ऑथराइजेशन से कनेक्ट करने पर क्या अलग होता है?

डैशबोर्ड पर Scrapy सर्वर का IPv4 पंजीकृत करें, तो meta proxy में http://198.51.100.23:8000 की तरह यूजरनेम और पासवर्ड के बिना डाल सकते हैं। सूची format=ip:port से भी प्राप्त कर सकते हैं। मल्टीपल सर्वर से स्पाइडर चलाते हैं तो हर सर्वर का IP पंजीकृत करें। अधिकतम 10 तक पंजीकृत कर सकते हैं।

सेशन वाले रिक्वेस्ट को एक ही IP से बांधने के लिए क्या करें?

लॉगिन या शॉपिंग कार्ट जैसे कुकी-आधारित फ्लो के लिए एक ही आईपी का उपयोग करना चाहिए। पहले अनुरोध में मेटा प्रॉक्सी सीधे डालें, और कॉलबैक में अगला अनुरोध बनाते समय response.meta के प्रॉक्सी मान को पास करें ताकि रोटेशन मिडलवेयर इसे न बदले। Scrapy के cookiejar मेटा कुंजी का उपयोग करने से कुकीज़ भी प्रति सत्र अलग हो जाती हैं।

एक सेशन में एक प्रॉक्सी और एक कुकी बंडल को पेयर करके रखें तो मल्टीपल सेशन एक साथ चलाने पर भी मिक्स नहीं होंगे।

import scrapy

PROXIES = [
    "http://spx_user:spx_pass@198.51.100.23:8000",
    "http://spx_user:spx_pass@198.51.100.24:8000",
]

class SessionSpider(scrapy.Spider):
    name = "sessions"

    def start_requests(self):
        for i, proxy in enumerate(PROXIES):
            yield scrapy.Request("https://example.com/", meta={"proxy": proxy, "cookiejar": i}, dont_filter=True)

    def parse(self, response):
        # follow-up request keeps the same proxy and the same cookie jar
        yield response.follow("/account", meta={"proxy": response.meta["proxy"], "cookiejar": response.meta["cookiejar"]}, callback=self.parse_account)

    def parse_account(self, response):
        self.logger.info("status %s via %s", response.status, response.meta["proxy"])

विफल प्रॉक्सी को अस्थायी रूप से हटाना चाहते हैं?

यदि आपको middleware के process_response में 403 या 429 प्रतिक्रिया मिलती है, तो आप उस प्रॉक्सी को कुछ मिनटों के लिए आराम दे सकते हैं और उसी अनुरोध को दूसरे प्रॉक्सी के साथ फिर से भेज सकते हैं। अनुरोध की प्रतिलिपि बनाकर meta से प्रॉक्सी को हटा दें और dont_filter को चालू करके वापस भेजें, तो अगला प्रॉक्सी उपयोग में आएगा।

आराम करने वाले प्रॉक्सी की सूची और पुनः उपयोग का समय शब्दकोश में प्रबंधित करना सरल है। एक ही IP को तुरंत पुनः उपयोग न करने से लक्षित साइट की सीमा को हटाने का समय मिलता है।

Scrapy में बैंडविड्थ को सेव करने के लिए क्या सेट करें?

Scrapy डिफॉल्ट रूप से सिर्फ HTML को रिसीव करता है, इसलिए यह ब्राउज़र टूल की तुलना में बहुत कम बैंडविड्थ का उपयोग करता है। इसमें HttpCompressionMiddleware डिफॉल्ट रूप से ऑन होता है जो कंप्रेस्ड रिस्पॉन्स को रिसीव करता है, जिससे ट्रांसफर की मात्रा और कम हो जाती है। यही कारण है कि शेयर्ड प्लान की मासिक बैंडविड्थ में बहुत सारे पेज कलेक्ट किए जा सकते हैं।

डुप्लीकेट पेज फेचिंग से बचने के लिए डेवलपमेंट के दौरान HTTPCACHE_ENABLED ऑन रखें - इससे हर बार टार्गेट साइट और प्रॉक्सी को रीफेच नहीं करना पड़ेगा। प्रोडक्शन में डुप्लीकेट URL फिल्टर (डिफ़ॉल्ट ऑन) मेनटेन रखें, और सिर्फ़ उन्हीं रिक्वेस्ट में dont_filter यूज़ करें जिन्हें वाकई में रीफेच करना ज़रूरी है।

अनावश्यक सबपेजेज में फैलने से बचने के लिए लिंक फॉलो करने की सीमा को संकीर्ण करना भी महत्वपूर्ण है। स्पष्ट स्क्रैपिंग सीमा निर्धारित करने से समय, बैंडविड्थ और टारगेट साइट का लोड सभी कम हो जाते हैं।

सामान्य समस्याओं का समाधान कैसे करें?

407 प्रतिक्रिया आने पर यूजरनेम और पासवर्ड जांचें। यदि पासवर्ड में विशेष वर्ण हैं, तो उन्हें प्रतिशत एन्कोडिंग करके डालें। TunnelError तब होता है जब प्रॉक्सी CONNECT अनुरोध प्राप्त नहीं कर पाता, पोर्ट HTTP पोर्ट है या नहीं जांचें।

यदि सभी अनुरोध एक ही IP से जाते हैं, तो मिडलवेयर क्रम संख्या HttpProxyMiddleware के बाद हो सकती है, या स्पाइडर में meta proxy सीधे डाला गया हो सकता है। settings.py के क्रम और स्पाइडर कोड की जांच करें।

Scrapy प्रॉक्सी सेटअप, मेटा प्रॉक्सी और रोटेटिंग मिडलवेयर | Socks5Proxy