Scrapy Splash를 이용한 웹 스크래핑: 단계별 가이드

Python으로 웹 스크래핑을 위한 Scrapy Splash를 마스터하세요. JavaScript 렌더링, 데이터 추출, 동적 페이지 처리를 효율적으로 배우세요.
5 분 읽기
Web Scraping with Scrapy Splash blog image

이 Scrapy Splash 가이드에서는 다음을 배우게 됩니다:

  • Scrapy Splash란 무엇인가
  • 단계별 튜토리얼로 Python에서 Scrapy Splash 사용 방법
  • Scrapy에서 Splash를 활용한 고급 스크래핑 기법
  • 이 도구로 웹사이트 스크래핑 시 제한 사항

자, 시작해 보겠습니다!

Scrapy Splash란 무엇인가요?

Scrapy Splash는 다음 두 도구의 통합을 의미합니다:

  • Scrapy: 웹사이트에서 필요한 데이터를 추출하기 위한 Python 오픈소스 크롤링 프레임워크 라이브러리.
  • Splash: 자바스크립트 중심의 웹 페이지를 렌더링하기 위해 설계된 경량 헤드리스 브라우저입니다.

강력한 도구인 Scrapy가 왜 Splash가 필요한지 궁금하실 수 있습니다. Scrapy는 HTML 파싱 기능(특히 Parsel에서 제공)에 의존하기 때문에 정적 사이트만 처리할 수 있습니다. 그러나 동적 웹사이트를 스크래핑할 때는 자바스크립트 렌더링을 처리해야 합니다. 일반적인 해결책은 자동화된 브라우저를 사용하는 것이며, Splash가 바로 이를 제공합니다.

Scrapy Splash를 사용하면 SplashRequest라는특수 요청을 Splash 서버로 보낼 수 있습니다. 이 서버는 자바스크립트를 실행하여 페이지를 완전히 렌더링하고 처리된 HTML을 반환합니다. 따라서 Scrapy Spider가 동적 페이지에서 데이터를 가져올 수 있게 합니다.

요약하자면, 다음과 같은 경우 Scrapy Splash가 필요합니다:

  • Selenium이나 Playwright에 비해 가벼운 솔루션을 선호하는 경우
  • Selenium이나 Playwright에 비해 가벼운 솔루션을 선호하는 경우
  • 스크래핑을 위해 전체 브라우저를 실행하는 오버헤드를 피하고 싶을 때.

Scrapy Splash가 요구사항을 충족하지 못할 경우 다음 대안을 고려하세요:

  1. Selenium: 자바스크립트 중심 웹사이트 스크래핑을 위한 완전한 브라우저 자동화 기능으로, Selenium Wire 같은 유용한 확장 기능을 제공합니다.
  2. Playwright: 일관된 크로스 브라우저 자동화와 강력한 API를 제공하는 오픈소스 브라우저 자동화 도구로, 여러 프로그래밍 언어를 지원합니다.
  3. Puppeteer: DevTools 프로토콜을 통해 Chrome을 자동화하고 제어하기 위한 고급 API를 제공하는 오픈 소스 Node.js 라이브러리입니다.

파이썬의 Scrapy Splash: 단계별 튜토리얼

이 섹션에서는 Scrapy Splash를 사용하여 웹사이트에서 데이터를 추출하는 방법을 이해하게 됩니다. 대상 페이지는 인기 있는 “Quotes to Scrape” 사이트의 특수 JavaScript 렌더링 버전입니다:

The target page of the tutorial

이 페이지는 일반적인 “Quotes to Scrape”와 유사하지만, JavaScript에 의해 트리거되는 AJAX 요청을 통해 데이터를 동적으로 로드하는 무한 스크롤을 사용합니다.

필요 조건

Python에서 Scrapy Splash를 사용하여 이 튜토리얼을 재현하려면 시스템이 다음 요구 사항을 충족해야 합니다:

해당 두 도구가 컴퓨터에 설치되어 있지 않다면 위 링크를 따라 설치하십시오.

필수 요소, 종속성 및 Splash 통합

프로젝트의 메인 폴더를 scrapy_splash/라고 가정합니다 . 이 단계가 완료되면 폴더 구조는 다음과 같아집니다:

scrapy_splash/
    └── venv/

여기서 venv/는 가상 환경을 포함합니다. venv/ 가상 환경 디렉터리는 다음과 같이 생성할 수 있습니다:

python -m venv venv

활성화하려면 Windows에서 다음 명령을 실행하세요:

venvScriptsactivate

macOS 및 Linux에서는 다음과 같이 실행합니다:

source venv/bin/activate

활성화된 가상 환경에서 다음 명령어로 종속성을 설치하세요:

pip install scrapy scrapy-splash

마지막으로 필요한 전제 조건으로, Docker를 통해 Splash 이미지를 가져와야 합니다:

docker pull scrapinghub/splash

그런 다음 컨테이너를 시작하세요:

docker run -it -p 8050:8050 --rm scrapinghub/splash

자세한 내용은 OS별 Docker 통합 안내를 참조하십시오.

Docker 컨테이너를 시작한 후, Splash 서비스가 아래 메시지를 기록할 때까지 기다리세요:

Server listening on http://0.0.0.0:8050

이 메시지는 Splash가 이제 http://0.0.0.0:8050에서 이용 가능함을 나타냅니다. 브라우저에서 해당 URL을 방문하면 다음과 같은 페이지가 표시됩니다:

The Splash service working

설정에 따라 http://0.0.0.0:8050 URL을 방문해도 Splash 서비스가 작동하지 않을 수 있습니다. 이 경우 다음 중 하나를 사용해 보십시오:

  • http://localhost:8050
  • http://127.0.0.1:8050

참고: Scrapy-Splash 사용 중에는 Splash 서버와의 연결이 유지되어야 합니다. 즉, CLI로 Docker 컨테이너를 실행한 경우 해당 터미널을 열어둔 상태로 유지하고, 이 절차의 다음 단계는 별도의 터미널에서 수행하세요.

훌륭합니다! 이제 Scrapy Splash로 웹 페이지를 스크래핑하는 데 필요한 모든 준비가 완료되었습니다.

1단계: 새 Scrapy 프로젝트 시작

scrapy_splash/ 메인 폴더 내에서 아래 명령어를 입력하여 새 Scrapy 프로젝트를 시작하세요:

scrapy startproject quotes

이 명령어로 Scrapy는 quotes/ 폴더를 생성합니다. 이 폴더 안에 필요한 모든 파일이 자동으로 생성됩니다. 결과 폴더 구조는 다음과 같습니다:

scrapy_splash/
   ├──  quotes/ 
   │       ├── quotes/
   │       │      ├── spiders/ 
   │       │      ├── __init__.py  
   │       │      ├── items.py  
   │       │      ├── middlewares.py 
   │       │      ├── pipelines.py  
   │       │      └── settings.py  
   │       │     
   │       └── scrapy.cfg  
   └── venv/  

완벽합니다! 새로운 Scrapy 프로젝트를 시작했습니다.

2단계: 스파이더 생성

대상 웹사이트를 크롤링할 새 스파이더를 생성하려면 quotes/ 폴더로 이동하세요:

cd quotes

그런 다음 다음 명령어로 새 스파이더를 생성하세요:

scrapy genspider words https://quotes.toscrape.com/scroll

다음과 같은 결과가 표시됩니다:

템플릿 'basic'을 사용하여 모듈 quotes.spiders.words 내부에 'words' 스파이더 생성됨:
  quotes.spiders.words

보시다시피 Scrapy가 spiders/ 폴더 내에 words.py 파일을 자동 생성했습니다. words.py 파일에는 다음 코드가 포함됩니다:

import scrapy

class WordsSpider(scrapy.Spider):
    name = "words"
    allowed_domains = ["quotes.toscrape.com"]
    start_urls = ["https://quotes.toscrape.com/scroll"]
    def parse(self, response):
        pass

이 파일에는 곧 동적 대상 페이지에서 필요한 스크래핑 로직이 포함될 것입니다.

만세! 대상 웹사이트를 스크래핑할 스파이더를 생성했습니다.

3단계: Splash 사용을 위한 Scrapy 설정

이제 Scrapy가 Splash 서비스를 사용할 수 있도록 설정해야 합니다. 이를 위해 settings.py 파일에 다음 구성을 추가하세요:

# Splash 로컬 서버 엔드포인트 설정
SPLASH_URL = "http://localhost:8050"
# Splash 다운로더 미들웨어 활성화
DOWNLOADER_MIDDLEWARES = {
    "scrapy_splash.SplashCookiesMiddleware": 723,
    "scrapy_splash.SplashMiddleware": 725,
    "scrapy.downloadermiddlewares.httpcompression.HttpCompressionMiddleware": 810,
}
# Splash 중복 제거 인자 필터 활성화
SPIDER_MIDDLEWARES = {
    "scrapy_splash.SplashDeduplicateArgsMiddleware": 100,
}

위 설정에서:

  • SPLASH_URL은 로컬 Splash 서버의 엔드포인트를 설정합니다. Scrapy가 자바스크립트 렌더링을 위해 요청을 보낼 위치입니다.
  • DOWNLOADER_MIDDLEWARES는 특정 미들웨어가 Splash와 상호작용할 수 있도록 활성화합니다. 특히:
    • SplashCookiesMiddleware는 Splash를 통해 요청을 수행할 때 쿠키를 처리하도록 Scrapy를 구성합니다.
    • SplashMiddleware는 Scrapy가 Splash를 통해 동적 콘텐츠의 실제 렌더링을 수행하도록 지시합니다.
    • HttpCompressionMiddleware는 다운로드된 콘텐츠에 대한 HTTP 압축 처리 방식을 변경합니다.
  • SPIDER_MIDDLEWARES는 동일한 Splash 인자를 가진 요청이 중복되지 않도록 보장하여 불필요한 부하를 줄이고 효율성을 높이는 데 유용합니다.

이러한 구성에 대한 자세한 내용은 공식 Scrapy-Splash 문서를 참조하십시오.

좋습니다! 이제 Scrapy가 Splash에 연결하고 자바스크립트 렌더링을 위해 프로그래밍 방식으로 사용할 수 있습니다.

4단계: 자바스크립트 렌더링을 위한 Lua 스크립트 정의

이제 Scrapy는 Splash와 통합하여 이 가이드의 대상 페이지와 같이 JavaScript에 의존하는 웹 페이지를 렌더링할 수 있습니다. 사용자 정의 렌더링 및 상호작용 로직을 정의하려면 Lua 스크립트를 사용해야 합니다. Splash는 JavaScript를 통해 웹 페이지와 상호작용하고 브라우저의 동작을 프로그래밍 방식으로 제어하기 위해 Lua 스크립트에 의존하기 때문입니다.

구체적으로, 아래 Lua 스크립트를 words.py에 추가하세요:

script = """
function main(splash, args)  
      splash:go(args.url)

      -- 사용자 정의 렌더링 스크립트 로직...

      return splash:html()
    end
"""

위 스니펫에서 script 변수는 서버에서 Splash가 실행할 Lua 로직을 포함합니다. 특히 이 스크립트는 Splash에게 다음을 지시합니다:

  1. splash:go() 메서드로 정의된 URL로 이동합니다.
  2. splash:html() 메서드로 렌더링된 HTML 콘텐츠를 반환합니다.

WordsSpider 클래스 내 start_requests() 함수에서 위 Lua 스크립트를 사용합니다:

def start_requests(self):
    for url in self.start_urls:
        yield SplashRequest(
            url,
            self.parse,
            endpoint="execute",
            args={"lua_source": script}
        )

위의 start_requests() 메서드는 Scrapy의 기본 start_requests()를 재정의합니다. 이렇게 하면 Scrapy Splash가 Lua 스크립트를 실행하여 페이지의 JavaScript로 렌더링된 HTML을 가져올 수 있습니다. Lua 스크립트 실행은 SplashRequest() 메서드의 "lua_source": script 인수를 통해 이루어집니다. 또한 "execute" Splash 엔드포인트 사용에 유의하세요(곧 자세히 알아볼 예정입니다).

Scrapy Splash에서 SplashRequest를 반드시 임포트하세요:

from scrapy_splash import SplashRequest

이제 words.py 파일에 페이지의 자바스크립트로 렌더링된 콘텐츠에 접근할 수 있는 올바른 Lua 스크립트가 준비되었습니다!

단계 #5: 데이터 파싱 로직 정의

시작하기 전에 대상 페이지의 quote HTML 요소를 살펴보고 파싱 방법을 이해하세요:

The inspected page

여기서 .quote로 인용문 요소를 선택할 수 있음을 확인할 수 있습니다. 인용문이 주어지면 다음을 얻을 수 있습니다:

  1. .text로 인용문 텍스트를 얻을 수 있습니다.
  2. .author로 인용문 작성자.
  3. .tags로 인용문 태그.

대상 페이지의 모든 인용문을 추출하는 스크래핑 로직은 다음 parse() 메서드를 통해 정의할 수 있습니다:

def parse(self, response):
    # CSS 선택자 가져오기
    quotes = response.css(".quote")
    for quote in quotes:
        yield {
            "text": quote.css(".text::text").get(),
            "author": quote.css(".author::text").get(),
            "tags": quote.css(".tags a.tag::text").getall()
        }

parse()는 Splash가 반환한 응답을 처리합니다. 구체적으로 다음과 같은 작업을 수행합니다:

  1. CSS 선택자 ".quote"를 사용하여 class가 quote인 모든 div 요소를 추출합니다.
  2. quote 요소를 반복하여 인용문의 이름, 저자, 태그를 추출합니다.

훌륭합니다! Scrapy Splash 스크래핑 로직이 완성되었습니다.

6단계: 모든 것을 통합하고 스크립트 실행하기

최종 words.py 파일은 다음과 같아야 합니다:

import scrapy
from scrapy_splash import SplashRequest

# 자바스크립트 렌더링을 위한 Lua 스크립트
script = """
function main(splash, args)  
      splash:go(args.url)

      return splash:html()
    end
"""

class WordsSpider(scrapy.Spider):
    name = "words"
    start_urls = ["https://quotes.toscrape.com/scroll"]
    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(
                url,
                self.parse,
                endpoint="execute",
                args={"lua_source": script}
            )
    def parse(self, response):
        quotes = response.css(".quote")
        for quote in quotes:
            yield {
                "text": quote.css(".text::text").get(),
                "author": quote.css(".author::text").get(),
                "tags": quote.css(".tags a.tag::text").getall()
            }

다음 명령어로 스크립트를 실행하세요:

scrapy crawl words

예상 결과는 다음과 같습니다:

All the quotes scraped with Scrapy Splash

원하는 결과는 다음과 같이 더 잘 시각화할 수 있습니다:

2026-03-18 12:21:55 [scrapy.core.scraper] DEBUG: <200 https://quotes.toscrape.com/scroll>에서 스크래핑됨
{'text': '“우리가 창조한 세상은 우리의 사고 과정이다. 우리의 사고를 바꾸지 않고서는 세상을 바꿀 수 없다.”', 'author': 'Albert Einstein', 'tags': ['change', 'deep-thoughts', 'thinking', 'world']}

2026-03-18 12:21:55 [scrapy.core.scraper] DEBUG: Scraped from <200 https://quotes.toscrape.com/scroll>
{'text': '“우리의 능력보다 훨씬 더, 우리의 선택이 진정한 우리를 보여준다, 해리.”', 'author': 'J.K. Rowling', 'tags': ['abilities', 'choices']}

# 생략...

2026-03-18 12:21:55 [scrapy.core.engine] INFO: 스파이더 종료 (완료)

출력에 관심 있는 데이터가 포함되어 있음을 유의하십시오.

Words``Spider 클래스에서 start_requests() 메서드를 제거하면 Scrapy가 데이터를 반환하지 않습니다. 이는 Splash 없이 JavaScript가 필요한 페이지를 렌더링할 수 없기 때문입니다.

아주 좋습니다! 첫 번째 Scrapy Splash 프로젝트를 완료했습니다.

Splash에 관한 참고 사항

Splash는 HTTP를 통해 통신하는 서버입니다. 이를 통해 어떤 HTTP 클라이언트든 Splash의 엔드포인트를 호출하여 웹 페이지를 스크래핑할 수 있습니다. 제공되는 엔드포인트는 다음과 같습니다:

  • execute: 사용자 정의 Lua 렌더링 스크립트를 실행하고 결과를 반환합니다.
  • render.html: 자바스크립트로 렌더링된 페이지의 HTML을 반환합니다.
  • render.png: 자바스크립트로 렌더링된 페이지의 이미지(PNG 형식)를 반환합니다.
  • render.jpeg: 자바스크립트로 렌더링된 페이지의 이미지(JPEG 형식)를 반환합니다.
  • render.har: 웹사이트와의 Splash 상호작용 정보를 HAR 형식으로 반환합니다.
  • render.json: 자바스크립트로 렌더링된 웹페이지에 대한 정보를 JSON 인코딩된 사전으로 반환합니다. 전달된 인자에 따라 HTML, PNG 및 기타 정보가 포함될 수 있습니다.

이러한 엔드포인트의 작동 방식을 더 이해하려면 render.html 엔드포인트를 살펴보세요. 다음 Python 코드로 엔드포인트에 연결하세요:

# pip install requests
import requests
import json

# Splash 엔드포인트 URL
url = "http://localhost:8050/render.html"

# Splash 엔드포인트에 POST 요청 전송
payload = json.dumps({
  "url": "https://quotes.toscrape.com/scroll" # 렌더링할 페이지의 URL
})
headers = {
  "content-type": "application/json"
}
response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)

이 코드 조각은 다음을 정의합니다:

  • render.html 엔드포인트를 호출하는 URL로 localhost의 Splash 인스턴스를 지정합니다.
  • 페이로드 내 스크래핑 대상 페이지.

위 코드를 실행하면 전체 페이지의 렌더링된 HTML을 얻을 수 있습니다:

<!DOCTYPE html>
<html lang="en">
  <head>
      <meta charset="UTF-8">
      <title>스크래핑할 인용문</title>
      <link rel="stylesheet" href="/static/bootstrap.min.css">
      <link rel="stylesheet" href="/static/main.css">
  </head>
  <body>
      <!-- 생략... -->
  </body>
</html>

Splash는 자바스크립트로 렌더링된 HTML을 독립적으로 처리할 수 있지만, SplashRequest와 함께 Scrapy Splash를 사용하면 웹 스크래핑이 훨씬 쉬워집니다.

Scrapy Splash: 고급 스크래핑 기법

이전 단락에서는 Splash 통합을 통한 기본적인 Scrapy 튜토리얼을 완료했습니다. 이제 Scrapy Splash로 고급 스크래핑 기법을 시도해 볼 시간입니다!

고급 스크롤링 관리

대상 페이지에는 무한 스크롤링 덕분에 AJAX를 통해 동적으로 로드되는 인용문이 포함되어 있습니다:

Infinite scrolling on the target page

무한 스크롤링과의 상호작용을 관리하려면 Lua 스크립트를 다음과 같이 변경해야 합니다:

script = """
function main(splash, args)
    local scroll_delay = 1.0  -- 스크롤 간 대기 시간
    local max_scrolls = 10    -- 수행할 최대 스크롤 횟수
    local scroll_to = 1000    -- 매번 스크롤할 픽셀 수

    splash:go(args.url)
    splash:wait(scroll_delay)

    local scroll_count = 0
    while scroll_count < max_scrolls do
        scroll_count = scroll_count + 1
        splash:runjs("window.scrollBy(0, " .. scroll_to .. ");")
        splash:wait(scroll_delay)
    end

    return splash:html()
end
"""

이 수정된 스크립트는 다음 변수들에 의존합니다:

  • max_scrolls는 수행할 최대 스크롤 횟수를 정의합니다. 이 값은 페이지에서 스크래핑하려는 콘텐츠 양에 따라 변경해야 할 수 있습니다.
  • scroll_to는 매번 스크롤할 픽셀 수를 지정합니다. 페이지 동작에 따라 값을 조정해야 할 수 있습니다.
  • splash:runjs()window.scrollBy() 자바스크립트 함수를 실행하여 지정된 픽셀 수만큼 페이지를 아래로 스크롤합니다.
  • splash:wait() 는 새 콘텐츠를 로드하기 전에 스크립트가 대기하도록 합니다. 대기 시간(초)은 scroll_delay 변수로 정의됩니다.

간단히 말해, 위 Lua 스크립트는 무한 스크롤 웹 페이지 시나리오에서 정의된 횟수의 스크롤을 시뮬레이션합니다.

words.py 파일의 코드는 다음과 같습니다:

import scrapy
from scrapy_splash import SplashRequest

# 무한 스크롤용 Lua 스크립트
script = """
function main(splash, args)
    local scroll_delay = 1.0  -- 스크롤 간 대기 시간
    local max_scrolls = 10    -- 수행할 최대 스크롤 횟수
    local scroll_to = 1000    -- 매번 스크롤할 픽셀 수

    splash:go(args.url)
    splash:wait(scroll_delay)

    local scroll_count = 0
    while scroll_count < max_scrolls do
        scroll_count = scroll_count + 1
        splash:runjs("window.scrollBy(0, " .. scroll_to .. ");")
        splash:wait(scroll_delay)
    end

    return splash:html()
end
"""

class WordsSpider(scrapy.Spider):
    name = "words"
    start_urls = ["https://quotes.toscrape.com/scroll"]
    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(
                url,
                self.parse,
                endpoint="execute",
                args={"lua_source": script}
            )
    def parse(self, response):
        # CSS 선택자 가져오기
        quotes = response.css("div.quote")
        for quote in quotes:
            yield {
                "text": quote.css("span.text::text").get(),
                "author": quote.css("span small.author::text").get(),
                "tags": quote.css("div.tags a.tag::text").getall()
            }

아래 명령어로 스크립트를 실행하세요:

scrapy crawl words

크롤러는 max_scrolls 변수에 따라 스크랩된 모든 인용문을 출력합니다. 예상 결과는 다음과 같습니다:

The new script outcome

이제 출력 결과에 이전보다 훨씬 많은 인용문이 포함된다는 점에 유의하세요. 이는 페이지가 성공적으로 스크롤되어 새로운 데이터가 로드되고 스크랩되었음을 확인시켜 줍니다.

완벽합니다! 이제 Scrapy Splash로 무한 스크롤을 처리하는 방법을 배웠습니다.

요소 대기

웹 페이지는 동적으로 데이터를 가져오거나 브라우저에서 노드를 렌더링할 수 있습니다. 이는 최종 DOM이 렌더링되는 데 시간이 걸릴 수 있음을 의미합니다. 웹사이트에서 데이터를 가져올 때 오류를 방지하려면, 페이지에서 요소가 로드될 때까지 기다린 후 상호작용해야 합니다.

이 예시에서 대기할 요소는 첫 번째 인용문의 텍스트입니다:

How to retrieve the text of the quotes on the target page

대기 로직을 구현하려면 다음과 같이 Lua 스크립트를 작성하세요:

script = """
function main(splash, args)
       splash:go(args.url)

       while not splash:select(".text") do
         splash:wait(0.2)
         print("waiting...")
       end

       return { html=splash:html() }
    end
"""

이 스크립트는 페이지에 텍스트 요소가 존재할 경우 0.2초 동안 대기하는 while 루프를 생성합니다. 페이지에 .text 요소가 있는지 확인하려면 splash:select() 메서드를 사용할 수 있습니다.

시간 대기

동적 콘텐츠 웹 페이지는 로드 및 렌더링에 시간이 소요되므로 HTML 콘텐츠에 접근하기 전에 몇 초간 대기할 수 있습니다. 이는 splash:wait() 메서드를 통해 다음과 같이 구현할 수 있습니다:

script = """
function main(splash, args)
       splash:wait(args.wait)       
       splash:go(args.url)
       return { html=splash:html() }
    end
"""

이 경우 스크립트가 대기해야 하는 초 수는 SplashRequest() 메서드의 Lua 스크립트 인자로 표현됩니다.

예를 들어, Lua 스크립트에 2초 동안 대기하도록 지시하려면"wait" : 2.0을 설정합니다:

import scrapy
from scrapy_splash import SplashRequest

script = """
function main(splash, args)
       splash:wait(args.wait)       
       splash:go(args.url)
       return { html=splash:html() }
    end
"""

class WordsSpider(scrapy.Spider):
    name = "words"
    start_urls = ["https://quotes.toscrape.com/scroll"]
    def start_requests(self):
        for url in self.start_urls:
            yield SplashRequest(
                url,
                self.parse,
                endpoint="execute",
                args={"lua_source": script, "wait": 2.0} # 2초 대기
            )
# ...

참고: 하드 대기(splash:wait())는 페이지가 로드된 후 진행되도록 보장하므로 로컬 테스트에 유용합니다. 그러나 불필요한 지연을 추가하여 성능과 확장성을 저해하므로 프로덕션 환경에는 적합하지 않습니다. 또한 사전에 정확한 대기 시간을 알 수 없습니다.

잘하셨습니다! Scrapy Splash에서 특정 시간 동안 대기하는 방법을 배웠습니다.

Scrapy Splash 사용의 한계

이 튜토리얼에서는 다양한 시나리오에서 Scrapy Splash를 활용해 웹 데이터를 추출하는 방법을 배웠습니다. 이 통합 방식은 간단하지만 몇 가지 단점이 있습니다.

예를 들어, Splash를 설정하려면 Docker로 별도의 Splash 서버를 실행해야 하므로 스크래핑 인프라에 복잡성이 추가됩니다. 또한 Splash의 Lua 스크립팅 API는 Puppeteer나 Playwright 같은 최신 도구들에 비해 다소 제한적입니다.

그러나 모든 헤드리스 브라우저와 마찬가지로 가장 큰 한계는 브라우저 자체에서 비롯됩니다. 안티 스크래핑 기술은 브라우저가 정상적으로 사용되는 것이 아니라 자동화되고 있음을 감지하여 스크립트 차단을 유발할 수 있습니다.

무한한 확장성을 위해 설계된 전용 클라우드 기반 스크래핑 브라우저인 Scraping Browser로이러한 어려움을 잊으세요. CAPTCHA 해결, 브라우저 지문 관리, 봇 방지 우회 기능을 포함하므로 차단될 걱정을 할 필요가 없습니다.

결론

이 글에서는 Scrapy Splash가 무엇이며 어떻게 작동하는지 알아보았습니다. 기본부터 시작하여 더 복잡한 스크래핑 시나리오까지 탐구했습니다.

또한 이 도구의 한계, 특히 봇 방지 및 스크래핑 방지 시스템에 취약하다는 점을 발견했습니다. 이러한 문제를 극복하기 위한 탁월한 해결책이 바로 Scraping Browser입니다. 이는 Bright Data가 제공하는 다양한 스크래핑 솔루션 중 하나에 불과합니다:

지금 Bright Data에 가입하고 무료 체험을 시작하여 스크래핑 솔루션을 테스트해 보세요.