본문 바로가기
파이썬/[파이썬을 활용한 웹 크롤링 완벽 가이드]

📌 6. Scrapy를 활용한 실전 프로젝트 (SQLite 데이터베이스 버전)

by 배불뚝 아저씨 2025. 2. 13.
반응형

1. 이전 강의 리뷰

이전 강의에서는 Scrapy 프레임워크를 활용하여 대량 데이터를 크롤링하는 방법을 배웠습니다. 이번 강의에서는 Hacker News에서 최신 기사 제목과 URL을 크롤링하고, Middleware와 SQLite 데이터베이스 저장 기능을 추가하여 완성도 높은 크롤러를 만들어 보겠습니다.


2. 실전 프로젝트 개요

  • 목표 사이트: Hacker News
  • 수집 데이터: 기사 제목, URL
  • 추가 기능: User-Agent 변경, SQLite 데이터베이스 저장, 중복 데이터 처리

3. Scrapy Middleware 설정 (자세한 설명)

middlewares.py에서 User-Agent를 랜덤하게 변경하여 크롤러가 차단되지 않도록 합니다.

import random
from scrapy import signals

class RandomUserAgentMiddleware:
    user_agents = [
        "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)..."
    ]

    def process_request(self, request, spider):
        ua = random.choice(self.user_agents)
        request.headers['User-Agent'] = ua
        spider.logger.info(f'User-Agent: {ua}')

settings.py에서 Middleware 활성화:

DOWNLOADER_MIDDLEWARES = {
    'my_scraper.middlewares.RandomUserAgentMiddleware': 400,
}

결과: Scrapy 실행 시 User-Agent가 랜덤으로 설정되며, 로그에 출력됩니다.


반응형

4. Scrapy Spider 작성 (뉴스 크롤링)

news_spider.py에서 기사 제목과 URL을 수집하는 Spider를 작성합니다.

import scrapy

class NewsSpider(scrapy.Spider):
    name = "news"
    start_urls = ["https://news.ycombinator.com/"]

    def parse(self, response):
        for article in response.css(".athing"):
            yield {
                'title': article.css("a.storylink::text").get(),
                'url': article.css("a.storylink::attr(href)").get()
            }

결과: scrapy crawl news 명령어 실행 시 기사 제목과 URL이 출력됩니다.


5. SQLite 데이터베이스 저장 (상세 설명)

pipelines.py에서 SQLite 데이터베이스 연결, 테이블 생성, 데이터 삽입 코드를 작성합니다.

import sqlite3
from scrapy.exceptions import DropItem

class SQLitePipeline:
    def open_spider(self, spider):
        self.conn = sqlite3.connect('news_data.db')
        self.cursor = self.conn.cursor()
        self.cursor.execute('''
            CREATE TABLE IF NOT EXISTS news (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                title TEXT,
                url TEXT UNIQUE
            )
        ''')

    def process_item(self, item, spider):
        try:
            self.cursor.execute("INSERT INTO news (title, url) VALUES (?, ?)", (item['title'], item['url']))
            self.conn.commit()
        except sqlite3.IntegrityError:
            raise DropItem("Duplicate entry found: %s" % item['url'])
        return item

    def close_spider(self, spider):
        self.conn.close()

settings.py에서 Pipeline 활성화:

ITEM_PIPELINES = {
    'my_scraper.pipelines.SQLitePipeline': 300,
}

결과: 크롤링 후 SQLite에서 SELECT * FROM news;를 실행하면 저장된 뉴스 데이터가 출력됩니다.


6. 크롤링 실행 결과

✅ Scrapy 실행 명령어

scrapy crawl news

✅ SQLite 출력 결과 (예시)

1 | Python 3.11 Released | https://www.python.org/...
2 | OpenAI launches new model | https://openai.com/...

🎯 이번 강의를 마치며

이번 프로젝트에서는 Scrapy를 활용한 뉴스 크롤러를 만들며 실전 경험을 쌓았습니다.

  • User-Agent 변경으로 차단 방지
  • SQLite에 데이터 저장 및 중복 방지
  • 크롤링 실행 후 결과 확인

Scrapy를 활용한 데이터 수집, 이제 여러분도 직접 시도해보세요! 🚀


🚀 다음 강의 예고

7부: Scrapy를 활용한 데이터 자동화 및 스케줄링

  • Scrapy를 주기적으로 실행하는 방법
  • 크론잡(Cron Job) 설정
  • Airflow를 이용한 데이터 파이프라인 구축
반응형

댓글