본문 바로가기

코딩과 AI와 자동화/크롤링

2편. 파이썬 Requests + BeautifulSoup로 크롤링 실습

반응형

1편「웹 크롤링의 개념과 기본 구조 정리」를 큰 그림 위주로 살펴봤습니다.

2편에서는 이론을 실제 코드로 옮겨 보겠습니다.
바로 파이썬 Requests + BeautifulSoup를 사용해 간단한 크롤러를 만들어 보겠습니다.


1. 이번 글에서 만들 실습 목표

이번 글에서는 다음 내용을 단계별로 다룹니다.

  1. 크롤링 환경 준비
    • 파이썬 버전, 라이브러리 설치
  2. Requests로 웹 페이지 가져오기
    • requests.get() 사용법, 상태 코드 확인
  3. BeautifulSoup으로 HTML 파싱
    • HTML 구조 이해, 태그 선택, 텍스트 추출
  4. 반복문으로 여러 개 데이터 추출
    • 글 목록(제목, 링크 등) 한 번에 가져오기
  5. 크롤링 시 꼭 지켜야 할 예의(에티켓)와 주의사항

최종적으로는, 블로그 글 목록 페이지에서
“글 제목 + 링크”를 가져오는 기본 템플릿을 완성하는 것이 목표입니다.


2. 크롤링 환경 준비하기

 

2.1 파이썬 버전 확인

우선 파이썬이 설치되어 있어야 합니다.
터미널(또는 CMD/PowerShell)을 열고 아래 명령어로 버전을 확인합니다.

python --version
# 또는
python3 --version

Python 3.8 이상이면 충분히 사용 가능합니다.

 

2.2 필요한 라이브러리 설치

이번 실습에서 사용할 핵심 라이브러리는 두 가지입니다.

  • requests : 웹 페이지에 HTTP 요청을 보내 HTML을 가져오는 역할
  • beautifulsoup4 : HTML 코드를 파싱하고, 원하는 태그/텍스트를 뽑아내는 역할

설치는 다음과 같이 진행합니다.

pip install requests
pip install beautifulsoup4

또는 한 번에:

pip install requests beautifulsoup4

설치가 완료되면 이제 바로 실습 코드를 작성할 준비가 끝났습니다.

 


3. Requests로 웹 페이지 가져오기

이제 실제로 웹 페이지 HTML을 가져오는 코드를 작성해 보겠습니다.

 

3.1 기본 요청 코드 구조

아래는 가장 기본적인 Requests 사용 예시입니다.

import requests

url = "https://example.com"  # 크롤링할 대상 URL (예시)

response = requests.get(url)  # GET 요청 전송
print(response.status_code)   # HTTP 상태 코드 확인
print(response.text[:500])    # HTML 내용 앞부분 500자만 출력

여기서 중요한 포인트는 두 가지입니다.

  1. status_code
    • 200이면 정상 응답
    • 404, 500 등은 오류 응답 → 크롤링 전에 항상 체크하는 습관이 좋습니다.
  2. response.text
    • 실제 HTML 내용이 문자열 형태로 들어 있습니다.

 

3.2 User-Agent 설정하기 (실무에서 거의 필수)

실제 서비스하는 웹사이트들은 봇/스크립트 요청을 차단하거나
이상한 요청을 의심하는 경우가 많습니다.

그래서 일반 브라우저처럼 보이도록 헤더에 User-Agent를 넣는 것이 좋습니다.

import requests

url = "https://example.com"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}

response = requests.get(url, headers=headers)
response.raise_for_status()  # 문제가 있으면 예외 발생

print(response.status_code)
  • raise_for_status() 를 사용하면
    상태 코드가 200이 아닐 때 에러를 발생시켜 바로 잡기 쉽습니다.

 


4. BeautifulSoup으로 HTML 파싱하기

이제 가져온 HTML을 BeautifulSoup으로 분석해 보겠습니다.

 

4.1 기본 파싱 코드

import requests
from bs4 import BeautifulSoup

url = "https://example.com"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}

res = requests.get(url, headers=headers)
res.raise_for_status()

html = res.text
soup = BeautifulSoup(html, "html.parser")  # HTML 파서 사용

# 페이지 제목 출력
print(soup.title)
print(soup.title.get_text())
  • BeautifulSoup(html, "html.parser")
    → HTML 문자열을 파싱해서 soup 객체로 만들어 줍니다.
  • soup.title
    → <title>...</title> 태그를 바로 가져옵니다.
  • get_text()
    → 태그 안의 텍스트만 깔끔하게 추출합니다.

 

4.2 특정 태그 하나 찾기 (find)

예를 들어, HTML 안에 이런 코드가 있다고 가정해 봅시다.

<h2 class="post-title">
  파이썬 크롤링 기초 배우기
</h2>

이 태그를 하나 찾고 싶다면:

title_tag = soup.find("h2", class_="post-title")
print(title_tag.get_text().strip())
  • "h2" : 태그 이름
  • class_="post-title" : class 속성이 post-title인 요소
  • strip() : 앞뒤 공백 제거

 

4.3 여러 개 태그 한 번에 찾기 (find_all)

블로그 글 목록처럼 여러 개의 제목 리스트를 가져오고 싶다면:

title_tags = soup.find_all("h2", class_="post-title")

for tag in title_tags:
    print(tag.get_text().strip())

이렇게 하면 post-title 클래스를 가진 모든 <h2> 태그를 가져와
반복문으로 돌면서 텍스트를 출력할 수 있습니다.

 


5. 실전 예시: 블로그 글 목록 크롤링 템플릿

이제까지 배운 내용을 합쳐서,
“블로그 글 목록 페이지에서 글 제목 + 링크를 추출하는 기본 템플릿”을 만들어 보겠습니다.

실제 서비스 도메인은 예시로 적고,
반드시 해당 사이트의 이용약관·robots.txt를 준수해야 합니다.

import requests
from bs4 import BeautifulSoup

# 1. 크롤링 대상 URL (예시용)
url = "https://example.com/blog"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
}

# 2. HTML 가져오기
res = requests.get(url, headers=headers)
res.raise_for_status()

# 3. BeautifulSoup으로 파싱
soup = BeautifulSoup(res.text, "html.parser")

# 4. 글 목록 영역에서 각 글 정보를 선택
# 예시: <div class="post"> 안에 <a class="post-link" href="...">제목</a>
posts = soup.select("div.post a.post-link")

results = []

for post in posts:
    title = post.get_text().strip()
    link = post["href"]

    # 상대 경로일 경우 절대 경로로 바꿔줘야 할 때도 있음
    # if link.startswith("/"):
    #     link = "https://example.com" + link

    results.append({
        "title": title,
        "link": link
    })

# 5. 결과 출력
for item in results:
    print(item["title"], "→", item["link"])
 

여기서 핵심 포인트는 다음과 같습니다.

  1. soup.select("CSS 선택자") 사용
    • div.post a.post-link :
      div.post 안에 있는 a.post-link 요소를 모두 가져온다는 의미
    • CSS 선택자에 익숙해지면 복잡한 구조도 깔끔하게 선택할 수 있습니다.
  2. post["href"]로 링크 가져오기
    • <a> 태그의 href 속성을 읽어서 URL을 추출합니다.
  3. 상대 경로 처리
    • "/post/1" 처럼 앞에 도메인이 없는 경우,
      기본 도메인과 합쳐서 절대 URL로 바꿔주는 로직을 추가할 수 있습니다.

 


6. 데이터를 리스트/파일로 저장하기 (기본형)

크롤링의 목적은 결국 데이터를 수집해서 활용하는 것입니다.
우선은 간단하게 파이썬 리스트에 모으는 형태까지만 보겠습니다.

위 코드에서 results가 바로 그런 역할을 합니다.

results = [
    {"title": "글 제목 1", "link": "https://..."},
    {"title": "글 제목 2", "link": "https://..."},
    ...
]

이후 단계에서:

  • CSV 파일로 저장
  • Pandas 데이터프레임으로 변환 후 분석
  • DB에 넣기

와 같은 작업을 이어갈 수 있습니다. (이 부분은 다음 편이나 후속 글에서 확장 가능)

 


7. 크롤링할 때 꼭 지켜야 할 에티켓과 주의사항

웹 크롤링은 기술적으로는 쉽지만, 법적·윤리적 이슈가 있을 수 있습니다.
그래서 다음 사항들을 꼭 지키는 것이 중요합니다.

  1. robots.txt 확인
    • 대부분의 사이트는 https://사이트주소/robots.txt에
      크롤링 허용/비허용 경로를 명시해 둡니다.
    • 허용되지 않은 경로는 크롤링하지 않는 것이 원칙입니다.
  2. 요청 간격 조절
    • 너무 빠르게 많은 요청을 보내면 서버에 부담을 줄 수 있습니다.
    • time.sleep(1) 등으로 사이사이 딜레이를 넣어 주는 것이 좋습니다.
  3. 개인정보 및 민감 정보 수집 금지
    • 이름, 연락처, 계정 정보 등 개인정보는 크롤링/수집 대상이 아닙니다.
    • 법적 문제가 될 수 있으니 절대 피해야 합니다.
  4. 서비스 약관(TOS) 준수
    • 일부 사이트는 약관에서 크롤링을 명시적으로 금지하기도 합니다.
    • 반드시 이용약관을 확인하고,
      상업적 이용이나 자동 수집이 허용되는지 확인해야 합니다.

8. 정리

이번 2편에서는:

  • requests로 웹 페이지 HTML을 가져오는 방법
  • BeautifulSoup으로 태그를 찾고, 텍스트/링크를 추출하는 방법
  • select, find, find_all 로 여러 개의 데이터를 반복해서 처리하는 방법
  • 크롤링 시 꼭 지켜야 할 기본 에티켓과 주의사항

을 실습 형태로 다뤄봤습니다.

반응형