Notice
Recent Posts
Recent Comments
Link
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

Nonamed Develog

[TIL][240910] Django와 웹 크롤링 본문

WHAT I LEARN/TIL

[TIL][240910] Django와 웹 크롤링

노네임드개발자 2024. 9. 10. 21:25

웹 크롤링이란?

웹 크롤링은 프로그램을 통해 웹사이트를 자동으로 탐색하고, 그 안에서 데이터를 추출하는 과정을 의미한다. 이 작업은 "크롤러" 또는 "스파이더"라 불리는 스크립트에 의해 수행되며, 크롤러는 웹 페이지의 링크를 따라가며 데이터를 수집한다. 주로 분석, 모니터링, 데이터베이스에 정보를 저장하는 등의 목적으로 사용된다.


웹 크롤링의 주요 개념

  • 요청(Requests): 크롤러는 HTTP 요청을 통해 웹 페이지의 내용을 가져온다. Python에서는 주로 requests 라이브러리를 사용해 웹 페이지에 요청을 보낸다.
  • 파싱(Parsing): HTML을 가져온 후, 이를 분석하고 필요한 데이터를 추출한다. BeautifulSoup(bs4) 또는 lxml과 같은 라이브러리를 사용해 HTML 구조를 파싱한다.
  • 탐색: 크롤러는 HTML에서 찾은 링크를 따라가며 다른 페이지를 탐색하여 데이터 수집을 진행한다.
  • 속도 조절(Rate Limiting): 웹 크롤링 시 서버에 부담을 주지 않기 위해 너무 많은 요청을 짧은 시간 안에 보내지 않도록 속도를 조절해야 한다. robots.txt 파일의 규칙을 준수하여 서버에 부담을 주지 않도록 해야 한다.
  • 데이터 저장: 수집한 데이터를 파일(CSV, JSON)이나 데이터베이스(SQL, NoSQL)에 저장할 수 있다.

Django에서 웹 크롤링을 활용하는 방법

Django는 주로 웹 개발에 사용되지만, 크롤링한 데이터를 자동으로 Django 애플리케이션에 삽입하는 데에도 사용할 수 있다. Django의 데이터베이스 모델, 관리 명령, 스케줄링 기능을 활용하여 크롤링한 데이터를 처리할 수 있다.


Django에서 웹 크롤링을 구현하는 이론적인 단계

크롤링 목적 정의: 먼저 어떤 데이터를 수집하고 그 데이터를 Django 프로젝트에서 어떻게 사용할지를 명확히 정해야 한다. 예를 들어, 전자 상거래 웹사이트의 상품 데이터를 수집하거나, 다양한 뉴스 웹사이트에서 블로그 게시물을 추출할 수 있다.

Django 모델 설정: 크롤링한 데이터를 저장할 모델을 models.py에 정의한다. 예를 들어, 상품 데이터를 수집하는 경우, 아래와 같이 Product 모델을 정의할 수 있다.

class Product(models.Model):
    title = models.CharField(max_length=255)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    description = models.TextField()
    image_url = models.URLField()
    source_url = models.URLField()

    def __str__(self):
        return self.title

 

크롤러 로직 작성 (독립 스크립트 또는 Django 관리 명령): Python의 requests와 BeautifulSoup 같은 라이브러리를 사용해 웹 페이지를 가져오고 파싱한다. 이를 독립된 Python 스크립트로 작성할 수 있지만, Django와 통합하려면 관리 명령(management command) 형태로 작성하는 것이 좋다.

 

import requests
from bs4 import BeautifulSoup
from django.core.management.base import BaseCommand
from products.models import Product

class Command(BaseCommand):
    help = '웹사이트에서 상품 데이터를 크롤링합니다.'

    def handle(self, *args, **kwargs):
        url = 'https://example.com/products'
        response = requests.get(url)
        soup = BeautifulSoup(response.text, 'html.parser')

        for product in soup.find_all('div', class_='product'):
            title = product.find('h2').text
            price = product.find('span', class_='price').text
            description = product.find('p', class_='description').text
            image_url = product.find('img')['src']
            source_url = product.find('a')['href']

            # Django 모델에 데이터 저장
            Product.objects.create(
                title=title,
                price=price,
                description=description,
                image_url=image_url,
                source_url=source_url
            )
            self.stdout.write(self.style.SUCCESS(f'{title} 크롤링 성공'))

 

 

이 스크립트는 특정 URL에서 제품 목록을 가져와 HTML을 파싱한 후, Django의 Product 모델에 데이터를 저장한다.

 

크롤링 프로세스 스케줄링: Django는 기본적으로 작업 스케줄링 기능이 포함되어 있지 않지만, Celery(비동기 작업 처리용) 또는 크론(cron) 작업(유닉스 기반 시스템)을 사용해 크롤링 작업을 정기적으로 실행할 수 있다.

 

0 3 * * * /path/to/virtualenv/bin/python /path/to/django/manage.py crawl_products

 

 

또는 분산 작업 처리가 필요한 경우 Django QCelery를 사용할 수도 있다.

 

크롤링한 데이터 뷰에서 처리하기: 크롤링한 데이터를 Django 모델에 저장한 후, 이를 웹 페이지에서 보여주려면 뷰에서 해당 데이터를 쿼리해야 한다. Django의 클래스 기반 뷰(CBVs)나 함수 기반 뷰(FBVs)를 사용해 저장된 데이터를 웹 페이지에 표시할 수 있다.

from django.shortcuts import render
from products.models import Product

def product_list(request):
    products = Product.objects.all()
    return render(request, 'products/product_list.html', {'products': products})

 

 

대규모 크롤링 처리: 대규모 웹 크롤링 작업이 필요하다면, Scrapy와 같은 크롤링 프레임워크를 사용하는 것이 더 효율적일 수 있다. Scrapy는 다중 스레드를 사용해 크롤링을 병렬로 처리할 수 있어 성능이 뛰어나며, Django와 통합하여 모델에 데이터를 저장하거나 API로 데이터를 전송할 수 있다.


윤리적인 웹 크롤링 고려 사항

  • robots.txt 파일 준수: 크롤링을 하기 전, 해당 웹사이트의 robots.txt 파일을 확인하여 크롤링 규칙을 준수해야 한다.
  • 서버 과부하 방지: 시간 간격을 두고 요청을 보내 서버에 과도한 부담을 주지 않도록 해야 한다. Python의 time.sleep()을 사용하거나 Scrapy의 속도 조절 기능을 활용할 수 있다.
  • 페이징 처리: 많은 웹사이트가 콘텐츠 목록을 페이징 처리한다. 크롤러가 페이지 내비게이션을 처리할 수 있도록 다음 링크를 따라가거나 특정 페이징 요소를 파싱하는 기능을 구현해야 한다.