Skip to Content
💻 코리아IT아카데미 신촌 - 프로그래밍 학습 자료
Python 프로그래밍Unit 10: 웹 크롤링 입문Topic 4: requests로 웹페이지 가져오기

Topic 4: requests로 웹페이지 가져오기 🌐

🎯 학습 목표

파이썬으로 웹페이지를 가져오는 첫걸음을 떼어봐요!

  • HTTP가 무엇인지 간단히 이해하기
  • requests 라이브러리 사용법 익히기
  • 웹페이지 내용 가져오기
  • 상태 코드 이해하기
  • 간단한 에러 처리하기

🌍 HTTP란 무엇일까요?

웹의 대화 방식

HTTP는 웹에서 정보를 주고받는 방법이에요. 마치 편지를 주고받는 것과 비슷해요!

👤 나 (클라이언트): "네이버 홈페이지 보여주세요!" 🖥️ 서버: "네, 여기 있습니다!" (HTML 전송)

HTTP 요청의 종류

우리가 주로 사용할 것들:

  • GET: 정보를 달라고 요청 (웹페이지 보기)
  • POST: 정보를 보내면서 요청 (로그인, 글쓰기)

🚀 첫 번째 웹페이지 가져오기

기본 사용법

import requests # 웹페이지 요청하기 response = requests.get("https://httpbin.org/html") # 결과 확인 print("상태 코드:", response.status_code) print("페이지 길이:", len(response.text))

단계별 설명

import requests # 1단계: URL 정하기 url = "https://httpbin.org/html" print(f"🌐 {url}에 접속합니다...") # 2단계: GET 요청 보내기 response = requests.get(url) print("✅ 응답을 받았습니다!") # 3단계: 응답 확인하기 print(f"📊 상태 코드: {response.status_code}") print(f"📏 페이지 크기: {len(response.text)} 글자") # 4단계: 내용 일부 보기 print("\n📄 페이지 내용 미리보기:") print(response.text[:200]) # 처음 200글자만

📊 응답(Response) 객체 이해하기

requests.get()은 Response 객체를 반환해요. 이 객체에는 많은 정보가 들어있어요!

Response 객체의 주요 속성

import requests response = requests.get("https://httpbin.org/json") # 1. 상태 코드 print(f"상태 코드: {response.status_code}") # 2. 텍스트 내용 print(f"텍스트 길이: {len(response.text)}") # 3. 바이트 내용 print(f"바이트 크기: {len(response.content)}") # 4. URL print(f"최종 URL: {response.url}") # 5. 헤더 정보 print(f"콘텐츠 타입: {response.headers.get('content-type')}") # 6. 응답 시간 print(f"응답 시간: {response.elapsed.total_seconds()}초")

text vs content 차이

# response.text - 문자열 (str) text_content = response.text print(type(text_content)) # <class 'str'> # response.content - 바이트 (bytes) byte_content = response.content print(type(byte_content)) # <class 'bytes'> # 언제 무엇을 사용? # - HTML, JSON 등 텍스트 → response.text # - 이미지, 파일 등 → response.content

🚦 HTTP 상태 코드 이해하기

상태 코드는 요청의 결과를 알려주는 3자리 숫자예요.

주요 상태 코드

코드의미설명
200OK성공! 정상적으로 받았어요
404Not Found페이지를 찾을 수 없어요
403Forbidden접근 권한이 없어요
500Server Error서버에 문제가 있어요

상태 코드 확인하기

import requests # 다양한 상태 코드 테스트 urls = [ "https://httpbin.org/status/200", # 정상 "https://httpbin.org/status/404", # 페이지 없음 "https://httpbin.org/status/500", # 서버 오류 ] for url in urls: response = requests.get(url) if response.status_code == 200: print(f"✅ {url} → 성공!") elif response.status_code == 404: print(f"❌ {url} → 페이지 없음") elif response.status_code == 500: print(f"🔥 {url} → 서버 오류") else: print(f"⚠️ {url} → 코드: {response.status_code}")

🎯 실용적인 예제

예제 1: 웹페이지 정보 수집

import requests def get_page_info(url): """웹페이지 기본 정보 가져오기""" print(f"🔍 {url} 분석 중...") # 요청 보내기 response = requests.get(url) # 정보 수집 info = { "url": url, "상태": response.status_code, "크기": f"{len(response.content):,} bytes", "타입": response.headers.get('content-type', '알 수 없음'), "서버": response.headers.get('server', '알 수 없음'), "응답시간": f"{response.elapsed.total_seconds():.2f}초" } # 출력 print("\n📊 페이지 정보:") for key, value in info.items(): print(f" {key}: {value}") return info # 테스트 get_page_info("https://www.python.org")

예제 2: 여러 페이지 확인하기

import requests import time def check_websites(urls): """여러 웹사이트 상태 확인""" results = [] for url in urls: print(f"확인 중: {url}") try: # 시작 시간 기록 start_time = time.time() # 요청 (타임아웃 5초) response = requests.get(url, timeout=5) # 응답 시간 계산 response_time = time.time() - start_time # 결과 저장 results.append({ "url": url, "status": response.status_code, "time": f"{response_time:.2f}초", "success": response.status_code == 200 }) if response.status_code == 200: print(f" ✅ 정상 ({response_time:.2f}초)") else: print(f" ⚠️ 코드: {response.status_code}") except requests.Timeout: print(f" ⏰ 타임아웃!") results.append({ "url": url, "status": "timeout", "time": "5초 초과", "success": False }) except Exception as e: print(f" ❌ 오류: {e}") results.append({ "url": url, "status": "error", "time": "-", "success": False }) # 서버 부담 줄이기 time.sleep(1) return results # 테스트할 사이트들 sites = [ "https://www.google.com", "https://www.github.com", "https://httpbin.org/delay/10", # 일부러 느린 응답 ] results = check_websites(sites) # 결과 요약 print("\n📊 전체 결과:") success_count = sum(1 for r in results if r["success"]) print(f"성공: {success_count}/{len(results)}")

🔤 인코딩 처리하기

한글 웹사이트를 가져올 때 중요해요!

인코딩이란?

컴퓨터가 문자를 저장하는 방식이에요:

  • UTF-8: 한글, 영어, 이모티콘 모두 OK! (가장 많이 사용)
  • EUC-KR: 오래된 한글 사이트
  • ISO-8859-1: 영어 위주

인코딩 확인 및 설정

import requests # 한글이 포함된 페이지 요청 response = requests.get("https://httpbin.org/encoding/utf8") # 인코딩 확인 print(f"서버가 알려준 인코딩: {response.encoding}") print(f"추측된 인코딩: {response.apparent_encoding}") # 잘못된 인코딩일 때 if response.encoding == 'ISO-8859-1': # 올바른 인코딩으로 변경 response.encoding = response.apparent_encoding print(f"변경된 인코딩: {response.encoding}") # 이제 한글이 제대로 보여요! print(response.text[:100])

🛡️ 기본 에러 처리

웹 크롤링에서는 여러 오류가 발생할 수 있어요. 미리 대비해봐요!

자주 발생하는 오류들

import requests def safe_get(url): """안전하게 웹페이지 가져오기""" try: # 타임아웃 설정 (10초) response = requests.get(url, timeout=10) # 상태 코드 확인 if response.status_code == 200: print("✅ 성공!") return response.text else: print(f"⚠️ 상태 코드: {response.status_code}") return None except requests.Timeout: print("⏰ 시간 초과: 응답이 너무 느려요") return None except requests.ConnectionError: print("🔌 연결 오류: 인터넷 연결을 확인하세요") return None except requests.RequestException as e: print(f"❌ 요청 오류: {e}") return None except Exception as e: print(f"💥 예상치 못한 오류: {e}") return None # 테스트 urls = [ "https://httpbin.org/html", # 정상 "https://httpbin.org/delay/20", # 느린 응답 "https://invalid-url-12345.com", # 잘못된 주소 ] for url in urls: print(f"\n시도: {url}") result = safe_get(url)

🎨 User-Agent 설정하기

일부 사이트는 브라우저인지 확인해요. User-Agent를 설정하면 브라우저처럼 보이게 할 수 있어요!

User-Agent란?

# User-Agent는 "나는 누구입니다"라고 알려주는 정보예요 # 기본 requests User-Agent response = requests.get("https://httpbin.org/user-agent") print("기본:", response.json()) # 브라우저처럼 보이게 하기 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } response = requests.get("https://httpbin.org/user-agent", headers=headers) print("변경:", response.json())

헤더 설정 예제

import requests def get_with_headers(url): """헤더를 포함한 요청""" # 브라우저처럼 보이는 헤더 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36', 'Accept': 'text/html,application/xhtml+xml', 'Accept-Language': 'ko-KR,ko;q=0.9,en;q=0.8', } response = requests.get(url, headers=headers) # 서버가 받은 헤더 확인 if url == "https://httpbin.org/headers": print("서버가 받은 헤더:") for key, value in response.json()['headers'].items(): print(f" {key}: {value}") return response # 테스트 get_with_headers("https://httpbin.org/headers")

💡 퀴즈: requests 이해도 체크

Q1. HTML 내용을 가져올 때 사용하는 속성은?

  1. response.html
  2. response.text
  3. response.content
  4. response.data

💡 정답 확인

정답: 2번 response.text

  • response.text: 텍스트 형태의 응답 (HTML, JSON 등)
  • response.content: 바이트 형태의 응답 (이미지, 파일 등)

Q2. 상태 코드 200은 무엇을 의미하나요?

💡 정답 확인

정답: 요청이 성공적으로 처리되었음을 의미

200 OK는 가장 일반적인 성공 상태 코드예요!

📝 실습: 날씨 정보 가져오기

import requests from datetime import datetime def get_weather_page(): """날씨 정보 페이지 가져오기 (연습용)""" # httpbin의 HTML 페이지 사용 (실제 날씨 사이트 대신) url = "https://httpbin.org/html" print("🌤️ 날씨 정보 가져오는 중...") # 헤더 설정 headers = { 'User-Agent': 'Weather Bot 1.0' } try: # 요청 보내기 response = requests.get(url, headers=headers, timeout=5) if response.status_code == 200: print("✅ 성공적으로 가져왔습니다!") # 페이지 정보 print(f"\n📊 페이지 정보:") print(f" 크기: {len(response.text):,} 글자") print(f" 응답 시간: {response.elapsed.total_seconds():.2f}초") print(f" 수집 시간: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") # HTML에서 제목 찾기 (간단한 방법) html = response.text if '<title>' in html and '</title>' in html: start = html.find('<title>') + 7 end = html.find('</title>') title = html[start:end] print(f" 페이지 제목: {title}") return response.text else: print(f"❌ 오류: 상태 코드 {response.status_code}") return None except Exception as e: print(f"❌ 오류 발생: {e}") return None # 실행 html_content = get_weather_page() if html_content: print(f"\n📄 HTML 미리보기:") print(html_content[:300])

✅ requests 마스터 체크리스트

✅ requests 마스터 체크리스트

🚀 다음 단계

requests로 웹페이지를 가져올 수 있게 되었나요? 이제 가져온 HTML에서 원하는 정보를 추출하는 BeautifulSoup을 배워볼게요!

Last updated on