통합

Shifter와 함께 사용 Scrapy

Shifter의 레지덴셜 및 ISP 프록시를 작은 다운로더 미들웨어를 통해 모든 Scrapy 스파이더에 연결하세요. 요청별 로테이션, 고정 세션, 스파이더별 지역 타겟팅을 단 20줄의 Python 코드로 구현할 수 있습니다.

빠른 시작

설치

pip install scrapy

기본 사용법

# 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

기능

Scrapy의 표준 다운로더 미들웨어 파이프라인에 연결하세요. 포크나 패치된 런타임이 필요 없습니다
기본값은 요청별 로테이션이며, 스티키 세션에는 `sid`를, N초 동안의 시간제 고정에는 `ttl-N`을 사용합니다
scrapy-playwright, scrapy-splash, scrapy-rotating-proxies와 즉시 호환됩니다
사용자 이름 매개변수를 통한 195개국 이상 Geo 타겟팅 - country, region, city, ASN
Scrapy Cloud, Scrapyd, GitHub Actions, Airflow 및 모든 오케스트레이션 레이어와 함께 작동합니다
Scrapy 2.x 및 Python 3.7+와 호환 - 동기 및 비동기 콜백 모두 지원

예시

Downloader Middleware(고정 세션)

Scrapy에 프록시를 연결하는 표준적인 방법입니다. 사용자 이름에 `sid`를 추가하면 스파이더의 모든 요청이 하나의 레지덴셜 IP를 공유하게 됩니다. 지역 타겟팅을 위해 `country-uk-city-london`을 추가하세요.

# 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"

요청별 로테이션

sid를 설정하지 마세요. 게이트웨이가 모든 요청마다 IP를 회전하도록 두세요. 각 페이지가 다른 방문자처럼 보여야 하는 페이지네이션 대상의 대용량 스크래핑에 유용합니다.

# 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()),
            }

국가별 스파이더 (동시 지역 스크래핑)

스파이더 클래스 하나를 만들고 실행 시점에 국가를 매개변수화하세요. 각각 자체 레지덴셜 IP 풀을 가진 여러 인스턴스를 병렬로 실행할 수 있습니다.

# 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 (JS 렌더링 페이지)

대상에 JavaScript가 필요할 때는 다운로더를 scrapy-playwright로 교체하세요. 프록시는 launch 옵션에 전달합니다 — Scrapy는 여전히 스케줄링과 파이프라인을 처리합니다.

# 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()
자주 묻는 질문

자주 묻는 질문

Scrapy와 Shifter 사용에 관한 일반적인 질문.

`request.meta['proxy']`를 Shifter URL로 설정하는 작은 다운로더 미들웨어를 작성한 다음, DOWNLOADER_MIDDLEWARES에 750보다 낮은 우선순위로 등록하십시오(HttpProxyMiddleware보다 먼저 실행되도록). Python 20줄이면 충분하며 SDK가 필요하지 않습니다.

process_request에서 새로운 sid를 생성하세요. 예를 들어 `secrets.token_hex(6)`을 사용하고 프록시 사용자명에 삽입합니다. 각 요청은 서로 다른 sid를 받게 되며, 따라서 Shifter의 게이트웨이로부터 서로 다른 레지덴셜 IP를 받게 됩니다. 외부 scrapy-rotating-proxies 의존성이 필요 없습니다.

전체 크롤링 실행에 대해 고정된 sid를 사용하세요. 스파이더 시작 시(또는 미들웨어 생성자에서) 한 번 생성하고 모든 요청에서 재사용하세요. `ttl-N`을 추가하면 IP 수명을 N초로 연장할 수 있습니다.

예. 스파이더 실행 시 `-a country=uk` 인수를 전달하거나, custom_settings에서 설정으로 노출하거나, 미들웨어 내부에서 읽으세요. 사용자 이름에 `country-uk`를 포함하여 프록시 URL을 구성하면, 해당 스파이더의 모든 요청이 영국 레지덴셜을 통과합니다.

예. PLAYWRIGHT_LAUNCH_OPTIONS에서 `server`, `username`, `password`로 프록시를 구성하세요. scrapy-playwright는 이를 Playwright의 launch 호출로 전달하며, 이 호출은 확장 프로그램 없이도 헤드리스 모드에서 basic-auth 인증을 처리합니다.

예. Scrapy Cloud 프로젝트는 단순히 Scrapy 스파이더일 뿐이며, 다운로더 미들웨어와 Shifter 프록시 URL은 프로젝트 tarball 안에 포함되어 배포됩니다. 소스에 커밋되지 않도록 인증 정보는 Scrapy Cloud 프로젝트 설정(또는 환경 변수)으로 추가하세요.

시작하기

Shifter 사용을 함께 시작하기 Scrapy

20줄 미들웨어를 통해 Shifter의 2억 500만+ 레지덴셜 및 ISP 프록시를 Scrapy 스파이더에 연결하세요. 요청별 로테이션, 고정 세션, 완전한 scrapy-playwright 지원을 제공합니다.

Shifter 무료로 체험하기몇 분 만에 설정. 언제든지 취소 가능.