Akashic Records

웹 크롤링에 robots.txt 적용하기 본문

Web Crawling for Beginners

웹 크롤링에 robots.txt 적용하기

Andrew's Akashic Records 2024. 4. 30. 14:06
728x90

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

 

웹 크롤링을 수행할 때 robots.txt 파일의 규칙을 준수하는 것은 매우 중요합니다. robots.txt는 웹사이트가 웹 크롤러에게 어떤 부분을 크롤링해도 되고 어떤 부분을 크롤링하지 말아야 하는지를 알려주는 파일입니다. 이 파일을 존중하고 준수함으로써, 웹사이트의 리소스를 보호하고, 크롤러가 차단되는 상황을 피할 수 있습니다.

 

robots.txt 파일 이해하기

robots.txt 파일은 주로 웹사이트의 루트 디렉토리에 위치하며, 다음과 같은 형식으로 작성됩니다:

User-agent: *
Disallow: /some-directory/
Disallow: /another-directory/

위 예에서 User-agent: *는 모든 크롤러에게 적용된다는 것을 의미하며, Disallow 지시어는 크롤러가 접근을 금지하는 디렉토리를 명시합니다.

 

파이썬에서 robots.txt 준수하기

파이썬의 urllib.robotparser 모듈을 사용하면 robots.txt의 규칙을 쉽게 읽고 이를 준수하는 크롤러를 만들 수 있습니다. 아래는 urllib.robotparser를 사용하는 예제 코드입니다:

import urllib.robotparser

# RobotFileParser 객체 생성
rp = urllib.robotparser.RobotFileParser()

# robots.txt 파일의 URL 설정
rp.set_url("http://example.com/robots.txt")

# robots.txt 파일 읽기
rp.read()

# 특정 URL에 대한 크롤링이 허용되는지 확인
url = "http://example.com/some-directory/"
user_agent = 'MyCrawler'

can_fetch = rp.can_fetch(user_agent, url)
print(f"Can fetch {url}: {can_fetch}")

 

코드 설명

  1. RobotFileParser 객체 생성: RobotFileParser 클래스의 인스턴스를 생성합니다.
  2. robots.txt 설정: set_url() 메서드를 통해 robots.txt 파일의 URL을 설정합니다.
  3. 파일 읽기: read() 메서드를 사용하여 robots.txt 파일을 읽고 파싱합니다.
  4. URL 접근 허용 확인: can_fetch() 메서드를 사용하여 특정 사용자 에이전트가 주어진 URL을 크롤링할 수 있는지 여부를 확인합니다.

주의사항

  • robots.txt 파일은 크롤링을 허용하지 않는 영역을 명확히 하기 위한 것이므로, 이를 준수하지 않을 경우 웹사이트로부터 IP 차단 등의 조치를 받을 수 있습니다.
  • 사이트의 리소스를 과도하게 사용하지 않도록 주의하며, 크롤링 속도를 조절하여 서버에 부담을 주지 않도록 합니다.
  • robots.txt 파일의 규칙은 웹사이트 운영자가 언제든지 변경할 수 있으므로, 주기적으로 파일을 확인하고 크롤러 설정을 갱신하는 것이 좋습니다.

웹 크롤링 코드

학습사이트 http://books.toscrape.com/를 대상으로 너비 우선 탐색(BFS) 크롤링을 수행하면서 robots.txt의 규칙을 확인하고 준수하는 크롤링 스크립트를 구현하는 예제를 제공하겠습니다. 이 예제에서는 Python의 urllib.robotparser를 사용하여 사이트의 robots.txt를 분석하고, 해당 규칙에 따라 크롤링이 가능한 페이지만 방문하도록 구현합니다.

 

필요한 라이브러리 설치

pip install requests beautifulsoup4

 

크롤링 스크립트 작성

import requests
from bs4 import BeautifulSoup
from urllib.parse import urljoin
import urllib.robotparser
from collections import deque
import sys
import io

def is_crawlable(url, user_agent='*'):
    rp = urllib.robotparser.RobotFileParser()
    rp.set_url(f"{url}/robots.txt")
    rp.read()
    return rp.can_fetch(user_agent, url)

def get_books_from_page(soup):
    """ 페이지에서 책들의 정보를 추출하는 함수 """
    books = []
    for book in soup.find_all('article', class_='product_pod'):
        title = book.find('h3').find('a')['title']
        price = book.find('p', class_='price_color').text
        stock = book.find('p', class_='instock availability').text.strip()
        books.append({'title': title, 'price': price, 'stock': stock})
    return books

def bfs_crawl(start_url, max_depth=3, user_agent='*'):
    """ 너비 우선 탐색을 사용하여 사이트 전체를 크롤링 """
    queue = deque([(start_url, 0)])  # URL과 현재 깊이를 저장합니다.
    visited = set()
    all_books = []

    while queue:
        current_url, depth = queue.popleft()
        if depth > max_depth:
            break
        if current_url in visited or not is_crawlable(current_url, user_agent):
            continue
        
        visited.add(current_url)

        print(f"Crawling: {current_url}")
        response = requests.get(current_url)
        soup = BeautifulSoup(response.text, 'html.parser')
        all_books.extend(get_books_from_page(soup))

        # 다음 페이지 링크 찾기
        next_button = soup.find('li', class_='next')
        if next_button:
            next_url = next_button.find('a')['href']
            next_page_url = urljoin(current_url, next_url)
            queue.append((next_page_url, depth+1))

    return all_books

if __name__ == "__main__":
    # 시작 URL
    sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
    start_url = 'http://books.toscrape.com/'
    books = bfs_crawl(start_url, 10)

    # 결과 출력
    for book in books:
        print(book)

 

코드 설명

  1. 로봇 규칙 확인: is_crawlable 함수는 주어진 URL에 대해 robots.txt를 참고하여 해당 사용자 에이전트가 URL을 크롤링할 수 있는지 여부를 반환합니다. RobotFileParser 객체를 사용하여 robots.txt를 읽고, can_fetch 메소드로 크롤링 가능 여부를 확인합니다.
  2. BFS 크롤링 로직: bfs_crawl 함수에서는 BFS 알고리즘을 사용하여 웹사이트를 크롤링합니다. 큐를 사용하여 방문할 페이지를 관리하고, 방문한 페이지는 visited 세트에 추가합니다. 각 페이지를 방문하기 전에 is_crawlable 함수를 호출하여 크롤링이 허용되는지 확인합니다.
  3. 페이지 처리: BeautifulSoup를 사용하여 페이지에서 필요한 정보(예: 인용구와 저자)를 추출합니다. 또한, 다음 페이지로의 링크를 찾아 큐에 추가합니다.

주의사항

  • 크롤링 스크립트는 사이트의 robots.txt 규칙을 준수하여, 사이트 운영에 부담을 주지 않도록 합니다.
  • robots.txt의 규칙이 변경될 수 있으므로 주기적으로 규칙을 확인하고 스크립트를 업데이트하는 것이 좋습니다.
728x90
Comments