Usa Shifter con Scrapy
Conecta los proxies residenciales e ISP de Shifter a cualquier spider de Scrapy mediante un pequeño middleware de descarga. Rotación por solicitud, sesiones persistentes y geolocalización por spider, todo en 20 líneas de Python.
Inicio rápido
Instalar
pip install scrapy Uso básico
# settings.py
DOWNLOADER_MIDDLEWARES = {
"myproject.middlewares.ShifterProxyMiddleware": 350,
"scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": 360,
}
# middlewares.py
class ShifterProxyMiddleware:
PROXY = (
"customer-USERNAME-country-us-sid-123ABC:"
"PASSWORD@p.shifter.io:443"
)
def process_request(self, request, spider):
request.meta["proxy"] = self.PROXY
# Run as usual:
# scrapy crawl my_spider Características
Ejemplos
Middleware de descarga (sesión persistente)
La forma estándar de conectar un proxy a Scrapy. Añade un `sid` al nombre de usuario y cada solicitud del spider compartirá una IP residencial. Añade `country-uk-city-london` para aplicar geolocalización.
# myproject/middlewares.py
import secrets
class ShifterProxyMiddleware:
"""Routes every Scrapy request through Shifter's residential pool."""
def __init__(self, country="us", city=None, ttl=300):
self.sid = secrets.token_hex(4)
parts = [
"customer-USERNAME",
f"country-{country}",
]
if city:
parts.append(f"city-{city}")
parts.append(f"sid-{self.sid}")
parts.append(f"ttl-{ttl}")
username = "-".join(parts)
self.proxy_url = f"http://{username}:PASSWORD@p.shifter.io:443"
@classmethod
def from_crawler(cls, crawler):
s = crawler.settings
return cls(
country=s.get("SHIFTER_COUNTRY", "us"),
city=s.get("SHIFTER_CITY"),
ttl=s.getint("SHIFTER_TTL", 300),
)
def process_request(self, request, spider):
request.meta["proxy"] = self.proxy_url
# myproject/settings.py
DOWNLOADER_MIDDLEWARES = {
"myproject.middlewares.ShifterProxyMiddleware": 350,
"scrapy.downloadermiddlewares.httpproxy.HttpProxyMiddleware": 360,
}
SHIFTER_COUNTRY = "uk"
SHIFTER_CITY = "london" Rotación por solicitud
No establezcas un sid: deja que la pasarela rote las IPs en cada solicitud. Útil para scraping de alto volumen en objetivos paginados donde cada página debe parecer un visitante diferente.
# myproject/middlewares.py
import secrets
class ShifterRotatingMiddleware:
"""Rotates the residential IP on every Scrapy request."""
PROXY_HOST = "p.shifter.io:443"
def process_request(self, request, spider):
# Unique sid per request -> guaranteed new IP for every fetch
unique_sid = secrets.token_hex(6)
username = (
f"customer-USERNAME-country-{spider.country}"
f"-sid-{unique_sid}"
)
request.meta["proxy"] = (
f"http://{username}:PASSWORD@{self.PROXY_HOST}"
)
# myproject/spiders/products.py
import scrapy
class ProductsSpider(scrapy.Spider):
name = "products"
country = "us" # consumed by the middleware
custom_settings = {
"DOWNLOADER_MIDDLEWARES": {
"myproject.middlewares.ShifterRotatingMiddleware": 350,
},
"CONCURRENT_REQUESTS": 32,
}
start_urls = [
f"https://example.com/products?page={i}" for i in range(1, 100)
]
def parse(self, response):
for card in response.css(".product-card"):
yield {
"title": card.css("h2::text").get(),
"price": card.css(".price::text").get(),
"url": response.urljoin(card.css("a::attr(href)").get()),
} Spiders por país (geo-scraping concurrente)
Crea una clase de spider y parametriza el país en tiempo de ejecución. Ejecuta varias instancias en paralelo, cada una con su propio pool de IPs residenciales.
# scrapy crawl localized -a country=uk
# scrapy crawl localized -a country=de
# scrapy crawl localized -a country=jp
import scrapy
class LocalizedSpider(scrapy.Spider):
name = "localized"
def __init__(self, country="us", *args, **kwargs):
super().__init__(*args, **kwargs)
self.country = country
self.start_urls = [
f"https://www.example.com/{country}/products",
]
def start_requests(self):
proxy = (
f"customer-USERNAME-country-{self.country}-sid-{self.country}-batch:"
f"PASSWORD@p.shifter.io:443"
)
for url in self.start_urls:
yield scrapy.Request(url, meta={"proxy": proxy}, callback=self.parse)
def parse(self, response):
for product in response.css(".product"):
yield {
"country": self.country,
"title": product.css("h2::text").get(),
"price": product.css(".price::text").get(),
} Scrapy + scrapy-playwright (páginas renderizadas con JS)
Cuando el objetivo necesita JavaScript, sustituye el descargador por scrapy-playwright. Pasa el proxy en las opciones de lanzamiento: Scrapy sigue gestionando la planificación y los pipelines.
# pip install scrapy-playwright
# playwright install chromium
# settings.py
DOWNLOAD_HANDLERS = {
"http": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
"https": "scrapy_playwright.handler.ScrapyPlaywrightDownloadHandler",
}
TWISTED_REACTOR = "twisted.internet.asyncioreactor.AsyncioSelectorReactor"
PLAYWRIGHT_LAUNCH_OPTIONS = {
"headless": True,
"proxy": {
"server": "http://p.shifter.io:443",
"username": "customer-USERNAME-country-fr-sid-789GHI",
"password": "PASSWORD",
},
}
# spider.py
import scrapy
class JsHeavySpider(scrapy.Spider):
name = "js_heavy"
start_urls = ["https://app.example.com/dashboard"]
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(
url,
meta={"playwright": True, "playwright_include_page": True},
callback=self.parse,
)
async def parse(self, response):
page = response.meta["playwright_page"]
await page.wait_for_selector(".widget")
widgets = await page.query_selector_all(".widget")
for w in widgets:
yield {"label": await w.text_content()}
await page.close() Preguntas frecuentes
Preguntas frecuentes sobre el uso de Shifter con Scrapy.
Escribe un pequeño middleware de descarga que establezca `request.meta['proxy']` en tu URL de Shifter, y luego regístralo en DOWNLOADER_MIDDLEWARES con una prioridad inferior a 750 (para que se ejecute antes que HttpProxyMiddleware). Veinte líneas de Python, sin SDK necesario.
Genera un sid nuevo en process_request, por ejemplo con `secrets.token_hex(6)`, e incrústalo en el nombre de usuario del proxy. Cada solicitud tendrá un sid diferente y, por tanto, una IP residencial distinta de la pasarela de Shifter. No se necesita la dependencia externa scrapy-rotating-proxies.
Usa un sid fijo para toda la ejecución del rastreo. Genéralo una vez al inicio del spider (o en el constructor del middleware) y reutilízalo en cada solicitud. Añade `ttl-N` para extender la vida útil de la IP a N segundos.
Sí. Pasa un argumento `-a country=uk` al ejecutar un spider, expónlo como ajuste en custom_settings, o léelo dentro de tu middleware. Construye la URL del proxy con `country-uk` en el nombre de usuario: cada solicitud de ese spider pasará por IPs residenciales del Reino Unido.
Sí. Configura el proxy en PLAYWRIGHT_LAUNCH_OPTIONS: `server`, `username`, `password`. scrapy-playwright los reenvía a la llamada de lanzamiento de Playwright, que gestiona el desafío de autenticación básica en modo headless sin necesidad de una extensión.
Sí. Los proyectos de Scrapy Cloud son simplemente spiders de Scrapy: tu middleware de descarga y la URL del proxy de Shifter se incluyen dentro del tarball de tu proyecto. Añade las credenciales como ajustes del proyecto en Scrapy Cloud (o como variables de entorno) para no incluirlas en el código fuente.
Empieza a usar Shifter con Scrapy
Integra los más de 205M de proxies residenciales y de ISP de Shifter en tus spiders de Scrapy mediante un middleware de 20 líneas. Rotación por solicitud, sesiones sticky y soporte completo para scrapy-playwright.