Advanced Scraping
웹 크롤링은 웹사이트에서 데이터를 추출하는 작업입니다. 대규모 크롤링을 다룰 때 Scrapy는 매우 유용한 도구입니다. Scrapy는 효율적이고 확장 가능한 웹 크롤링 및 스크래핑 프레임워크로, 대규모 데이터를 쉽게 처리할 수 있습니다.
Large-Scale Scraping
Scrapy
는 대규모 웹 크롤링 프로젝트에 적합한 프레임워크입니다. Scrapy
는 요청을 처리하고, 응답을 파싱하며, 데이터를 저장하는 기능을 기본적으로 제공합니다. 대규모 크롤링을 할 때는 Scrapy
를 통해 여러 페이지를 동시에 처리할 수 있습니다.
pip install scrapy
# 새로운 프로젝트 생성
scrapy startproject myproject
# 새로운 spider 생성
scrapy genspider myspider example.com
Structure
myproject/
│
├── scrapy.cfg
│
└── myproject/
├── __init__.py
├── items.py
├── middlewares.py
├── pipelines.py
├── settings.py
└── spiders/
├── __init__.py
└── myspider.py
scrapy.cfg
: 프로젝트 설정 파일myproject/spiders/
: 크롤링할 사이트의 URL을 정의하는 파일myproject/items.py
: 스크래핑한 데이터를 저장할 클래스myproject/pipelines.py
: 데이터를 처리하는 파이프라인myproject/settings.py
: 프로젝트의 설정 파일
Usage
Scrapy
는 비동기식 요청을 처리하며, 각 요청이 끝날 때까지 기다리지 않고 다른 요청을 처리합니다. 이를 통해 크롤링 속도를 크게 향상시킬 수 있습니다. 또한, 분산 크롤링 기능도 지원하여 크롤링 작업을 여러 서버에서 분산시킬 수 있습니다.
import scrapy
class MySpider(scrapy.Spider):
name = 'myspider'
start_urls = ['https://example.com']
def parse(self, response):
title = response.css('h1::text').get()
print('Page Title:', title) # Page Title: Example Domain
Designing a Scraper
Scrapy에서 크롤러는 데이터를 추출하는 역할을 합니다. parse
함수는 응답을 처리하고 데이터를 추출하는데 사용됩니다. 기본적으로 웹 페이지의 HTML을 파싱하고, 필요한 데이터를 추출하여 저장합니다.
class MySpider(scrapy.Spider):
name = 'myspider'
start_urls = ['https://example.com']
def parse(self, response):
page_title = response.css('h1::text').get()
page_url = response.url
yield {
'title': page_title,
'url': page_url
}
Data Pipelines
Scrapy는 크롤링한 데이터를 처리하는 파이프라인(pipeline)
기능을 제공합니다. 파이프라인은 데이터가 크롤러에서 추출된 후 저장되기 전에 처리할 수 있는 곳입니다.
class MyPipeline:
def process_item(self, item, spider):
item['title'] = item['title'].upper() # 제목을 대문자로 변환
return item
파이프라인을 활성화하려면 settings.py
에서 설정을 추가합니다:
# settings.py
ITEM_PIPELINES = {
'myproject.pipelines.MyPipeline': 1,
}
Handling AJAX
AJAX는 웹 페이지에서 데이터를 동적으로 로드하는 데 사용됩니다. Scrapy는 기본적으로 AJAX 요청을 처리하지 않지만, JavaScript를 통해 동적으로 로드된 데이터를 크롤링할 수 있습니다.
AJAX 요청을 처리하려면 scrapy-selenium
을 사용하여 JavaScript 렌더링을 처리하거나, 직접 AJAX 요청을 캡처하여 데이터를 추출할 수 있습니다.
pip install scrapy-selenium
from scrapy_selenium import SeleniumRequest
class MySpider(scrapy.Spider):
name = 'myspider'
start_urls = ['https://example.com/ajax']
def start_requests(self):
yield SeleniumRequest(url=self.start_urls[0], callback=self.parse)
def parse(self, response):
data = response.css('.ajax-data::text').get()
print('AJAX Data:', data) # AJAX Data: Dynamic Content
API Scraping
웹사이트에서 데이터를 직접 크롤링하는 대신, API를 통해 데이터를 요청하고 받아오는 방법도 있습니다. 많은 웹사이트는 데이터를 API로 제공하며, 이를 사용하여 효율적으로 데이터를 수집할 수 있습니다.
import scrapy
import json
import requests
from scrapy.http import JsonRequest
class MySpider(scrapy.Spider):
name = 'myspider'
start_urls = ['https://example.com']
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(url=url, callback=self.parse)
def parse(self, response):
# 웹 페이지에서 데이터 크롤링
page_title = response.css('h1::text').get()
page_url = response.url
# API에서 데이터 요청
api_url = 'https://api.example.com/data'
api_data = self.fetch_api_data(api_url)
# 웹 페이지 데이터와 API 데이터를 결합
item = {
'title': page_title,
'url': page_url,
'api_data': api_data, # API에서 받은 데이터 추가
}
# 데이터 저장
yield item
def fetch_api_data(self, api_url):
# API에서 JSON 데이터 요청
response = requests.get(api_url)
api_data = response.json()
return api_data
OpenAPI 문서를 통해 API 엔드포인트와 데이터를 요청하는 방법을 이해할 수 있습니다. Scrapy를 사용하면 API로부터 받은 데이터를 크롤링한 웹 페이지의 데이터와 함께 저장할 수 있습니다.