Короткие ответы
Где указать прокси для запроса Scrapy?
В meta["proxy"] конкретного Request. HttpProxyMiddleware обрабатывает это значение и авторизацию. Остальные запросы паука не получают маршрут только потому, что он был задан первому.
Как передать пароль со специальными символами?
В URL компоненты исходного имени и пароля кодируются по отдельности через quote(..., safe=""). Не кодируйте URL целиком и не перекодируйте уже собранный результат.
Что проверяет ответ 200?
Пример требует статус 200 назначения и JSON с корректным IP. Это не проверка парсера, страны или доступа к другому сайту. CONNECT и ответ назначения оцениваются отдельно.
Можно включить больше повторов после 407?
Сначала исправьте авторизацию и убедитесь в правильном хосте, порте и полном имени. Повторы неверных реквизитов не решают проблему. Отказ назначения требует отдельной проверки разрешения.
Зафиксируйте среду, а не только название библиотеки
Английский пример закрепляет Scrapy 2.19.0 и использует его документированную модель запуска. Прежде чем переносить код, сверьте runtime, зависимости и собственный обработчик загрузки. Установка пакета не подтверждает маршрут. Не выдавайте параметры другого HTTP-клиента или браузера за настройки Scrapy.
python -m pip install "scrapy==2.19.0"
python -c "import scrapy; print(scrapy.__version__)"Официальный HttpProxyMiddleware описывает выбор прокси и обработку реквизитов. При явном meta["proxy"] запрос не должен случайно полагаться на переменные другого процесса. Дальнейшие запросы формируйте с осознанной политикой маршрута.
Скопируйте согласованные реквизиты
Откройте Connection builder · English, выберите пул, страну, сессию и HTTP. Полное имя пользователя несёт эти параметры. Пароль аккаунта и API-ключ не заменяют пароль шлюза. При использовании арендованного порта берите его собственные доставленные данные.
Пример принимает PROXY_USER, отдельно спрашивает пароль и собирает URL. Переменная PROXY_SERVER при необходимости задаёт только HTTP-адрес шлюза без пути и встроенной авторизации. Получившийся URL содержит секрет: не печатайте его, не передавайте в аналитику и не сохраняйте в общих журналах.
Проверьте один запрос до рабочего паука
Сохраните scrapy_check.py и запустите его в подготовленной среде. Код отключает автоматические повторы, перенаправления, cookies, подробные журналы и удалённое управление для этого диагностического сценария. После успешного туннеля отдельно проверяются статус, JSON и формат IP.
Код сохранён целиком из английского владельца. ROBOTSTXT_OBEY=False относится только к запланированному echo-запросу; не переносите это исключение в сбор по произвольным сайтам.
import getpass
import ipaddress
import os
from urllib.parse import quote, urlsplit
import scrapy
from scrapy.crawler import CrawlerProcess
class ProxyCheck(scrapy.Spider):
name = "proxy_check"
ok = False
async def start(self):
yield scrapy.Request(
"https://api.portproof.org/v1/echo-ip", callback=self.parse, errback=self.failed,
meta={"proxy": self.proxy, "handle_httpstatus_all": True},
)
def parse(self, response):
if response.status != 200:
print("HTTP response after CONNECT:", response.status)
return
try:
payload = response.json()
if not isinstance(payload, dict) or not isinstance(payload.get("ip"), str):
raise ValueError("Expected an IP address")
address = ipaddress.ip_address(payload["ip"])
except (ValueError, KeyError, TypeError):
print("Check failed: invalid echo response")
return
self.ok = True
print("HTTP", response.status, "exit", address)
def failed(self, failure):
print("No destination response:", failure.type.__name__)
if __name__ == "__main__":
server = os.environ.get("PROXY_SERVER", "http://gw.portproof.org:7000")
try:
gateway = urlsplit(server)
valid = (
gateway.scheme == "http" and gateway.hostname
and gateway.port is not None and gateway.username is None
and gateway.password is None and gateway.path in ("", "/")
and not gateway.query and not gateway.fragment
)
except ValueError:
valid = False
if not valid:
raise SystemExit("Use an HTTP gateway URL without credentials or a path")
user = os.environ.get("PROXY_USER", "")
if not user or ":" in user:
raise SystemExit("Set PROXY_USER to your complete proxy username")
password = getpass.getpass("Proxy password: ")
proxy = (
"http://" + quote(user, safe="") + ":" + quote(password, safe="")
+ "@" + gateway.netloc
)
process = CrawlerProcess(settings={
"TWISTED_REACTOR_ENABLED": True,
"DOWNLOAD_HANDLERS": {
"https": "scrapy.core.downloader.handlers.http11.HTTP11DownloadHandler",
},
"DOWNLOAD_VERIFY_CERTIFICATES": True,
"CONCURRENT_REQUESTS": 1,
"DOWNLOAD_TIMEOUT": 20,
"DOWNLOAD_MAXSIZE": 65536,
"RETRY_ENABLED": False,
"REDIRECT_ENABLED": False,
"METAREFRESH_ENABLED": False,
"ROBOTSTXT_OBEY": False, # This diagnostic schedules only the echo URL.
"COOKIES_ENABLED": False,
"LOG_ENABLED": False,
"TELNETCONSOLE_ENABLED": False,
"REMOTE_CONTROL_ENABLED": False,
})
crawler = process.create_crawler(ProxyCheck)
process.crawl(crawler, proxy=proxy)
process.start()
raise SystemExit(0 if crawler.spider and crawler.spider.ok else 1)Разберите CONNECT и результат назначения
| Наблюдение | Что известно | Чего оно не доказывает |
|---|---|---|
| Нет ответа назначения | Ошибка возникла до пригодного HTTP-ответа | Что нужно ещё больше попыток |
| CONNECT отклонён | Туннель не установлен | Что ошибка пришла от приложения назначения |
| После CONNECT пришёл иной статус | Назначение вернуло этот ответ | Что реквизиты прокси неверны |
| 200 и корректный IP | Echo обработал данный запрос | Что страна или парсер проверены |
При 407 проверьте строку и данные авторизации; используйте отдельную инструкцию. При ошибке туннеля — CONNECT-диагностику. Не меняйте пароль сайта для исправления пароля шлюза и не отключайте проверку сертификатов.
Планируйте ограничения для настоящего сбора
В коде один конкурентный запрос, таймаут 20 секунд и максимум 64 KiB. Эти значения ограничивают фикстуру, а не определяют разрешённую нагрузку или возможности аккаунта. Рабочий паук дополнительно требует конечной очереди, общего срока задачи, правил повторов и ограничений каждого назначения.
Не путайте CONCURRENT_REQUESTS с числом стартов в секунду. Быстрые ответы могут освобождать слоты много раз. Для разрешённого мониторинга учитывайте robots.txt, условия источника и его указания при 429. Перенесите необходимые политики в собственный проект до увеличения объёма.
Содержимое проверяйте до подсчёта пригодной записи. Пустой шаблон с 200 и другой вариант товара не становятся правильным результатом. Руководство по разрешённому сбору помогает определить поля, дубли и стоимость полезного результата.
Проверьте реальную задачу и текущую покупку
После echo выполните небольшой разрешённый образец своим пауком. Запишите попытки, пригодные записи и весь расход; расчёт ГБ ведёт к текущей цене. Пул и сессия не резервируют устройство за покупателем.
Редакция от 2 ноября 2026 года сохраняет исторически проверенный английский код без изменения тела. Новый Scrapy-пакет не устанавливался, живой шлюз и сторонний сбор здесь не запускались. Точность кода и полей не является заявлением о скорости или будущем ответе назначения.
Допустимое использование
Выполняйте только разрешённые действия в пределах правил назначения. Сохраняйте учётные данные и личное содержимое в тайне; соблюдайте политику допустимого использования · English.