Интегрируйте прокси Catproxy в свои проекты Scrapy для надёжного парсинга в больших масштабах. Изучите передовые практики на реальном примере.
Scrapy - мощный фреймворк для масштабного парсинга. Лучший способ управления прокси в Scrapy - использовать кастомный Downloader Middleware. Это позволяет централизовать логику прокси и держать пауков чистыми.
Сначала создадим middleware, который будет прикреплять учётные данные прокси к каждому запросу.
В вашем проекте Scrapy откройте файл middlewares.py.
Добавьте следующий класс. Он считывает учётные данные из settings.py и легко расширяется для работы с динамическими параметрами.
middlewares.py
# my_project/middlewares.pyimport base64class ScrapyCatproxyProxyMiddleware: def process_request(self, request, spider): # По умолчанию — статические настройки прокси proxy_user = spider.settings.get('PROXY_USER') proxy_pass = spider.settings.get('PROXY_PASS') # Позволяет spider’ам переопределять прокси для каждого запроса if 'proxy_username_params' in request.meta: params = request.meta['proxy_username_params'] proxy_user = f"{spider.settings.get('PROXY_USER')}{params}" # Задайте прокси для запроса request.meta['proxy'] = f"http://{spider.settings.get('PROXY_HOST')}:{spider.settings.get('PROXY_PORT')}" # Добавьте заголовок Proxy-Authorization для авторизации proxy_auth = f"{proxy_user}:{proxy_pass}" auth_header = 'Basic ' + base64.b64encode(proxy_auth.encode()).decode() request.headers['Proxy-Authorization'] = auth_header spider.logger.info(f"Using proxy user: {proxy_user} for {request.url}")
Это продвинутое middleware позволяет передавать динамические параметры (например, -country-de) из паука в middleware с помощью request.meta['proxy_username_params'].
Теперь включим middleware и добавим ваши учётные данные.
Откройте файл settings.py.
Добавьте базовые учётные данные прокси.
Включите ScrapyCatproxyProxyMiddleware в DOWNLOADER_MIDDLEWARES.
settings.py
# my_project/settings.py# --- Catproxy Proxy Credentials ---PROXY_HOST = "proxy.catproxy.net"PROXY_PORT = 5555PROXY_USER = "PROXY_USERNAME" # Without any parametersPROXY_PASS = "PROXY_PASSWORD"# --- Enable the Middleware ---# The number (e.g., 610) should be high enough to run after default middlewares,# but before any middlewares that might depend on the proxy.DOWNLOADER_MIDDLEWARES = { 'my_project.middlewares.ScrapyCatproxyProxyMiddleware': 610,}
Ваша базовая настройка завершена! Любой запрос от любого паука в вашем проекте теперь будет автоматически использовать прокси Catproxy.
Теперь используем созданное middleware для парсинга всех игр со скидками из магазина Steam. Этот паук стал намного чище, поскольку вся логика прокси находится в middleware.
Обратите внимание, насколько чист этот паук. Он сосредоточен исключительно на логике парсинга и передаче динамических параметров в middleware.
spiders/steam_specials_spider.py
import scrapyimport randomclass SteamSpecialsSpider(scrapy.Spider): name = "steam_specials" start_urls = ["https://store.steampowered.com/specials"] def start_requests(self): # Create a unique session ID for this job session_id = f"steam-special-{random.randint(1000, 9999)}" # Define the parameters we want to pass to our middleware # We will use the same sticky session for all pages proxy_params = f"-country-us-session-{session_id}" cookies = {'birthtime': '568022401', 'wants_mature_content': '1', 'steamCountry': 'US|...'} for url in self.start_urls: yield scrapy.Request( url, callback=self.parse, # Pass our dynamic parameters to the middleware meta={'proxy_username_params': proxy_params}, cookies=cookies, headers={ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36' } ) def parse(self, response): # Extract data from the current page games = response.css('a.salepreviewwidgets_SaleItemBrowserRow_y9MSd') if not games: self.logger.warning("No games found on page. The CSS selector might be outdated.") return for game in games: yield { 'title': game.css('div.salepreviewwidgets_StoreSaleWidgetTitle_3jI46::text').get(), 'original_price': game.css('div.salepreviewwidgets_StoreOriginalPrice_2e_2G::text').get(), 'discount_price': game.css('div.salepreviewwidgets_StoreSalePriceBox_Wh0L8::text').get(), } # Find and follow the "Next" page link next_page_link = response.css('a.paging_Arrow_2JZe3[href*="specials?page="]:last-of-type').get() if next_page_link: # Scrapy automatically carries over the `meta` dictionary, # so our middleware will continue to use the same session! yield response.follow(next_page_link, callback=self.parse) else: self.logger.info("Last page reached. Finishing crawl.")
CSS-селекторы могут меняться! Такие сайты, как Steam, часто обновляют дизайн. CSS-селекторы в этом примере актуальны на момент написания, но в будущем может потребоваться их обновление.
Лучшая практика: Паук чист и сфокусирован на том, что парсить. Middleware обрабатывает, как подключиться. Это надёжный и масштабируемый подход.
Динамическое управление: Паук может легко изменить геолокацию или сессию для любого запроса, просто изменив значение proxy_username_params в словаре meta.
Переиспользование кода:ScrapyCatproxyProxyMiddleware теперь может использоваться всеми пауками в вашем проекте без дублирования кода.