Akashic Records

URL 너비 우선 탐색(BFS) 웹 크롤러 본문

Web Crawling for Beginners

URL 너비 우선 탐색(BFS) 웹 크롤러

Andrew's Akashic Records 2024. 4. 24. 10:37
728x90

위는 파이썬 웹 크롤러 프로그램의 개념적 다이어그램을 나타낸 이미지입니다. 이 이미지는 컴퓨터 화면에 코드가 표시되고, 웹 서버와의 데이터 요청 및 응답을 상징하는 화살표가 흐름을 보여주는 모습을 단순하고 교육적인 스타일로 표현하고 있습니다. 컴퓨터는 'Web Crawler'로, 웹 서버는 'Website'로 레이블이 붙어 있습니다.

 

웹 페이지의 <a> 태그 링크를 따라가면서 연속적으로 URL을 찾아 분석하는 웹 크롤러를 만드는 것은 깊이 우선 탐색(DFS)이나 너비 우선 탐색(BFS)의 로직을 따를 수 있습니다. 여기서는 너비 우선 탐색을 사용한 기본적인 웹 크롤러를 설계하겠습니다. 이 크롤러는 시작 URL에서 링크를 추출하고, 각 링크를 방문하여 다시 링크를 추출하는 과정을 반복합니다. 몇 가지 단순화된 가정을 하고, 외부 링크는 무시하고 동일 도메인 내에서만 크롤링하도록 설정하겠습니다.

 

필요한 라이브러리 설치

pip install beautifulsoup4 requests

 

BFS 웹 크롤러 코드

import requests
from urllib.parse import urljoin, urlparse
from bs4 import BeautifulSoup
from collections import deque

def is_valid_url(base_url, url):
    """ 동일 도메인 내의 URL인지 검사하고, 유효한 링크인지 확인합니다. """
    parsed_base = urlparse(base_url)
    parsed_url = urlparse(url)
    if parsed_base.netloc != parsed_url.netloc:
        return False
    if not parsed_url.scheme.startswith('http'):
        return False
    return True

def get_links(url):
    """ 주어진 URL 페이지에서 모든 링크를 추출합니다. """
    response = requests.get(url)
    soup = BeautifulSoup(response.text, 'html.parser')
    links = set()
    for link in soup.find_all('a', href=True):
        full_url = urljoin(url, link['href'])
        if is_valid_url(url, full_url):
            links.add(full_url)
    return links

def crawl(start_url, max_depth=3):
    """ 너비 우선 탐색(BFS)을 사용하여 웹 크롤링을 실행합니다. """
    visited = set()
    queue = deque([(start_url, 0)])  # URL과 현재 깊이를 저장합니다.

    while queue:
        current_url, depth = queue.popleft()
        if depth > max_depth:
            break
        if current_url not in visited:
            visited.add(current_url)
            print(f"Visiting: {current_url} at depth {depth}")
            try:
                for link in get_links(current_url):
                    if link not in visited:
                        queue.append((link, depth + 1))
            except requests.exceptions.RequestException as e:
                print(f"Error fetching {current_url}: {e}")

    print("Crawling finished.")

# 시작 URL 설정
start_url = 'http://books.toscrape.com/'
crawl(start_url, max_depth=3)

 

코드 설명

  1. 함수 is_valid_url: 주어진 URL이 시작 URL과 동일한 도메인을 가지는지 확인하고, http 또는 https 프로토콜을 사용하는지 검사합니다.
  2. 함수 get_links: BeautifulSoup을 사용하여 페이지에서 모든 <a> 태그의 href 속성을 읽고, 절대 URL로 변환합니다. 유효한 URL만 반환합니다.
  3. 함수 crawl: BFS를 사용하여 웹사이트를 크롤링합니다. 큐(deque)를 사용하여 각 URL과 현재 깊이를 관리합니다. 설정된 최대 깊이(max_depth)에 도달하면 더 이상 큐에 추가하지 않습니다.

이 코드는 매우 기본적인 웹 크롤러의 예제로, 실제 사용 시에는 로봇 배제 표준(robots.txt) 준수, 링크 루프 감지, 오류 처리 등의 기능을 추가로 고려해야 할 수 있습니다. 또한, 실제 크롤링을 수행하기 전에 대상 웹사이트의 이용 약관을 확인하는 것이 중요합니다.

학습 대상 사이트

웹 크롤링 연습을 위한 실습 대상 사이트를 선택할 때는 법적으로 문제가 없고, 데이터 구조가 비교적 간단하며, 다양한 유형의 데이터를 포함하는 사이트를 선택하는 것이 좋습니다. 다음은 웹 크롤링 실습에 적합한 몇 가지 사이트를 추천합니다:

  1. Books to Scrape
    • URL: http://books.toscrape.com/
    • 설명: 웹 스크레이핑 실습을 위해 만들어진 사이트로, 다양한 책에 대한 정보(제목, 가격, 재고 상태 등)가 있습니다. 각 책의 상세 페이지로 이동할 수 있는 링크도 제공되어 있어 페이지 내 이동 및 데이터 추출 연습에 좋습니다.
  2. Quotes to Scrape
    • URL: http://quotes.toscrape.com/
    • 설명: 인용구와 저자 정보를 제공하는 사이트로, 페이지 네비게이션, 로그인 기능을 통한 접근, 태그별 인용구 조회 등 다양한 크롤링 기술을 연습할 수 있습니다.
  3. Mockaroo
    • URL: https://mockaroo.com/
    • 설명: 실제 데이터와 유사한 무작위 데이터를 생성하여 다운로드할 수 있습니다. API를 통해 데이터를 가져오는 연습도 가능하며, 크롤링보다는 API 사용에 더 초점이 맞춰져 있습니다.
  4. Toscrape Books (지역 기반 데이터)
    • URL: https://books.toscrape.com/
    • 설명: 지역 기반 데이터를 포함하고 있으며, 각 지역별로 다양한 책의 데이터를 수집할 수 있습니다. 페이지 내 이동 및 데이터 추출 연습에 적합합니다.
  5. OpenWeatherMap (API 연습용)
    • URL: https://openweathermap.org/
    • 설명: 날씨 정보 API를 제공합니다. 웹 크롤링과는 다르게 API를 통해 데이터를 받아오는 방법을 연습할 수 있으며, API 사용 방법을 이해하는 데 도움이 됩니다.

이 사이트들은 학습 및 실습 목적으로 사용하기에 적합하며, 다양한 데이터 타입과 웹 페이지 구조를 경험할 수 있어 웹 크롤링 기술을 향상시키는 데 도움이 됩니다. 웹 크롤링 연습을 할 때는 항상 해당 사이트의 robots.txt 파일을 확인하고, 사이트의 이용 약관을 준수하며, 과도한 요청으로 사이트에 부담을 주지 않도록 주의해야 합니다.

728x90
Comments