본문 바로가기
카테고리 없음

BeautifulSoup 입문

by kik328288 2026. 5. 12.

크롤링 입문 (Python, HTML, 파싱)

웹 크롤링은 신입 개발자가 가장 빠르게 결과를 손에 잡는 분야 가운데 하나다. 회의록 자동 수집·뉴스 모니터링·가격 비교·논문 메타데이터 정리처럼 일상 업무 곳곳에 활용할 수 있고, 입문 단계의 도구가 워낙 잘 정돈되어 있어 한 시간이면 첫 결과물을 만들 수 있다. 본 글은 파이썬 기반 크롤링의 가장 표준 입문 도구인 requestsBeautifulSoup를 중심으로, HTML 파싱의 기본 원리부터 robots.txt 같은 법적 주의사항까지 한 번에 정리한다(출처: BeautifulSoup 공식 문서). 제가 학교 동아리 행사에서 처음 BS4로 행사 페이지를 긁어 보면서 가장 충격이었던 게 30줄 안에 결과가 떨어지는 일이었고, 그 후로는 "크롤링은 거창한 분야가 아니라 일상 자동화의 시작점"이라는 인상을 손끝으로 받아들였다.

 

크롤링이 풀어 주는 일상 자동화 문제

웹 크롤링이란 사람이 직접 브라우저로 보는 웹 페이지의 데이터를 프로그램이 자동으로 가져와 구조화된 데이터로 바꾸는 작업을 가리킨다. 일반적으로 두 단계로 구성되는데, 첫째는 HTTP 요청으로 페이지의 HTML을 가져오는 단계이고, 둘째는 그 HTML에서 필요한 데이터만 추출하는 파싱(parsing) 단계이다. 여기서 파싱이란 단순한 텍스트 덩어리를 구조 정보를 가진 객체 트리로 변환해 원하는 부분만 골라낼 수 있게 만드는 분해 절차를 가리킨다.

실전에서 크롤링이 빛을 발하는 영역은 의외로 거창하지 않다. 매일 아침 뉴스 헤드라인을 자동 수집해 디스코드 채널에 올리거나, 학교 수강신청 페이지의 잔여 자리를 1분마다 확인하거나, 채용 공고 페이지에서 키워드가 포함된 글만 추려내는 일이 모두 30~50줄짜리 스크립트로 끝난다. 솔직히 제 경험상 학교 친구가 가장 부러워한 자동화도 거창한 AI가 아니라 "수강신청 잔여 자리 알림"이었고, 이건 BS4 한 줄로 끝나는 작업이었다.

다만 크롤링에는 항상 두 가지 전제 조건이 있다. 첫째, 대상 사이트가 robots.txt에서 크롤링을 허용하는지 확인해야 한다는 점이다. robots.txt란 사이트 운영자가 검색 엔진이나 크롤러에게 허용·차단 경로를 알려 주는 표준 텍스트 파일로, 도메인 루트에 위치한다. 둘째, 과도한 요청으로 서버에 부담을 주지 않아야 한다는 점이다. 일반적으로 요청 사이 1~3초의 지연(sleep)을 두는 것이 예의로 통하며, 한국에서는 저작권법과 정보통신망법에 따라 무단 자동 수집이 제한될 수 있어 주의가 필요하다.

requests와 BeautifulSoup 30분 입문

파이썬 크롤링의 표준 조합은 requests로 HTTP 요청을 보내고 BeautifulSoup(BS4)로 응답 HTML을 파싱하는 흐름이다. 두 패키지 모두 한 줄로 설치된다.

pip install requests beautifulsoup4 lxml

기본 사용법은 다음과 같다. 다음 예시는 한 페이지의 제목과 모든 링크를 뽑아내는 가장 단순한 형태다.

import requests
from bs4 import BeautifulSoup

url = "https://example.com"
res = requests.get(url, headers={"User-Agent": "edu-crawler/1.0"})
res.raise_for_status()

soup = BeautifulSoup(res.text, "lxml")

print(soup.title.text)             # 페이지 제목
for a in soup.select("a[href]"):    # 모든 링크
    print(a.get_text(strip=True), "->", a["href"])

여기서 User-Agent란 요청을 보낸 클라이언트의 종류를 서버에 알려 주는 HTTP 헤더이며, 정직하게 정체를 밝히는 것이 크롤링의 기본 예절이다. lxml은 파싱 백엔드로, 파이썬 기본 html.parser보다 5~10배 빠르고 대용량 페이지에서도 안정적이라는 점이 강점이다.

가장 자주 쓰는 두 메서드가 find/find_allselect다. find_all은 CSS의 클래스·태그를 인자로 받아 매칭되는 모든 요소를 반환하고, select는 CSS 선택자 문법을 그대로 사용해 더 표현력 있게 쓸 수 있다. 솔직히 제 경험상 입문 단계에서는 select 한 가지만 익혀 두는 게 가장 가성비가 높았는데, 브라우저의 개발자 도구에서 "Copy selector" 한 번이면 그대로 갖다 쓸 수 있어 학습 곡선이 거의 0에 가깝다는 점이 결정적이었다.

# 다양한 선택자 예시
soup.select("h2.title")              # 클래스 매칭
soup.select("div#main > p")          # 자식 선택자
soup.select("ul.menu li:nth-of-type(2)")  # 위치 선택자
soup.select_one("meta[property='og:image']")["content"]  # 메타 태그 값

결과 저장, robots.txt 점검, 윤리적 크롤링

수집한 데이터는 일반적으로 CSV·JSON·SQLite 셋 중 하나로 저장하며, 단발성 분석에는 pandas.to_csv가, 누적 수집에는 SQLite가 가장 편하다. 다음은 뉴스 헤드라인을 매일 누적 저장하는 가장 단순한 형태다.

import requests, sqlite3, time
from bs4 import BeautifulSoup
from datetime import datetime

con = sqlite3.connect("news.db")
con.execute("""CREATE TABLE IF NOT EXISTS news(
    fetched_at TEXT, title TEXT, link TEXT UNIQUE)""")

res = requests.get("https://example.com/news",
                   headers={"User-Agent": "edu-crawler/1.0"}, timeout=10)
soup = BeautifulSoup(res.text, "lxml")

for a in soup.select("h3.headline a"):
    try:
        con.execute("INSERT INTO news VALUES (?, ?, ?)",
                    (datetime.now().isoformat(),
                     a.get_text(strip=True), a["href"]))
    except sqlite3.IntegrityError:
        pass    # 이미 저장된 링크는 건너뜀
    time.sleep(0.2)

con.commit(); con.close()

여기서 UNIQUE 제약과 IntegrityError 처리가 핵심이다. 같은 링크가 다시 들어왔을 때 중복 저장을 막아 주는 한 줄짜리 안전망이며, 누적형 크롤러를 운영할 때 반드시 들어가야 할 패턴이다.

법적·윤리적 점검 흐름은 다음 네 가지로 정리된다. 첫째, https://대상도메인/robots.txt를 직접 열어 Disallow 경로를 확인한다. 둘째, 사이트의 이용약관에서 크롤링 가능 여부를 명시한 항목이 있는지 본다. 셋째, 요청 간 지연(1

3초)을 두고 동시 요청 수를 1

2개로 제한한다. 넷째, 수집한 데이터를 재배포할 계획이 있다면 저작권과 개인정보 보호법을 함께 검토한다(출처: 한국인터넷진흥원 KISA). 솔직히 이건 예상 밖이었는데, 학교 프로젝트에서 한 번 robots.txt를 빠뜨렸다가 사이트 운영자로부터 메일을 받은 경험이 있고, 그 후로는 어떤 단발성 스크립트라도 robots 확인을 가장 먼저 하는 습관이 자리 잡았다. 입문에서 가장 중요한 도구는 BS4 한 줄보다도 이 네 가지 점검 체크리스트 한 장이다. 다음 글에서는 자바스크립트로 동적으로 만들어지는 페이지를 다루기 위한 브라우저 자동화(Selenium·Playwright)를 이어 다룬다.


메타 디스크립션: 파이썬 requests와 BeautifulSoup로 30분 안에 첫 크롤러를 만드는 입문 흐름, CSS 선택자 활용, SQLite 누적 저장, 그리고 robots.txt를 포함한 윤리적 크롤링 점검 체크리스트까지 한 번에 정리합니다.


소개 및 문의 · 개인정보처리방침 · 면책조항

© 2026 블로그 이름