CodeGym /Java Course /Python SELF KO /"다음" 링크를 사용한 데이터 수집

"다음" 링크를 사용한 데이터 수집

Python SELF KO
레벨 34 , 레슨 1
사용 가능

1. 페이지 나누기(pagination) 소개

필요한 데이터가 한 페이지에만 있다고 누가 그러더냐? 대부분은 여러 페이지에서 데이터를 뽑아내야 하고, 심지어 사이트 전체에 퍼져있기도 해. 그래서 처음 마주하게 되는 도전 중 하나는 데이터를 페이지로 나누는 거야. 그리고 이를 모으는 매력적인 작업이 바로 pagination(페이지 나누기)야.

그렇지, pagination은 단순히 Google 검색 결과 다음 페이지로 가는 것이 아니라, 웹 스크레이퍼가 "이걸 어떻게 하면 자동화할 수 있을까?"라고 고민하는 걸 포함하지.

Pagination은 콘텐츠가 많은 긴 페이지를 피하기 위해 사이트에서 데이터를 조직화하는 방법이야. 대신, 데이터는 페이지로 나뉘어서 "다음" 또는 "Next" 같은 링크를 추가해 한 페이지에서 다른 페이지로 이동할 수 있게 해. 이건 중요한 개념이야. 왜냐면 너는 웹 스크레이퍼로서, 누군가에게 다섯 번째 페이지에 숨겨져 있어서 데이터를 얻지 못했다고 말하고 싶지 않을 테니까 말이야.

2. 여러 페이지에서 데이터 스크레이핑할 때의 문제

첫 번째 문제는 이해하기 쉽고 예측 가능한 URL이 없다는 점이야. 어떤 사이트는 페이지 사이를 이동할 때 URL이 크게 변하지 않아. 이러면 자동화 작업이 꽤나 까다로워져. 예를 들어, page=1, page=2 대신에 x=abc, x=def 같은 패턴 없는 URL을 마주칠 수도 있어.

두 번째 문제는 바로 봇 방어야. 몇몇 사이트는 같은 IP 주소에서 온 요청의 수를 적극적으로 모니터링해. 요청이 너무 많으면 일시적(혹은 영구적)으로 차단당할 수 있어.

걱정하지 마! 이제부터 진정한 스크레이퍼처럼 이런 어려움을 피하는 방법을 배울 거야.

3. Pagination 우회

기술과 전략

  1. URL 구조 분석: 보통 페이지는 URL에 페이지 번호를 표시하는 매개변수를 사용해, 예를 들어 ?page=2. 만약 이런 걸 발견했다면, 축하해! 음 금광을 발견한 거야, pagination 우회용으로 말이지!
  2. "다음" 링크 검색: 때로는 URL을 예측하기 어려워. 그럴 땐 "다음" 또는 "Next" 링크를 찾아 따라가야 해.
  3. AJAX 요청 사용: 어떤 사이트는 페이지를 새로고침하지 않고 AJAX로 데이터를 가져와. 이럴 경우, 이런 요청을 가로채고 재현해야 해.

이제 실습으로 들어가자!

Pagination 우회와 데이터 수집 스크립트 예제

스크립트 예제를 살펴보자:

Python

import requests
from bs4 import BeautifulSoup

# 한 페이지에서 데이터 가져오는 함수
def get_data_from_page(url):
    response = requests.get(url)
    if response.status_code == 200:
        soup = BeautifulSoup(response.text, 'html.parser')
        # 여기서 soup에서 데이터를 추출 — 예제
        data = soup.find_all('div', class_='data-class')
        for item in data:
            print(item.text)  # 데이터를 출력하거나 저장
    else:
        print(f"페이지를 가져올 수 없음: {url}")

# Pagination 우회를 위한 주요 로직
def scrape_all_pages(start_url):
    current_url = start_url
    while current_url:
        get_data_from_page(current_url)
        soup = BeautifulSoup(requests.get(current_url).text, 'html.parser')
        # "다음" 링크 찾기 시도
        next_button = soup.find('a', text='다음')
        if next_button:
            current_url = next_button['href']
        else:
            current_url = None

# 첫 번째 페이지에서 스크레이핑 시작
start_url = 'http://example.com/page=1'
scrape_all_pages(start_url)

이건 pagination 작업 원리를 보여주는 기본 예제야. 너가 작업 중인 사이트 구조에 맞추어 조정해야 해.

세션 관리 및 user-agent 사용

사이트에 많은 요청을 보낼 때, 세션을 사용하고 user-agent를 변경하면 차단 위험을 줄일 수 있어.

Python

headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}

session = requests.Session()
session.headers.update(headers)

response = session.get('http://example.com')

이 구조는 빈 헤더로 요청을 보내는 것보다 브라우저를 더 잘 에뮬레이트해.

4. 실질적 구현

이제 기본을 알았으니, 조금 더 복잡한 문제로 넘어가자. 페이지 링크에 예측 불가능한 매개변수가 포함되어 있고 AJAX를 사용해 데이터를 가져와야 하는 경우를 살펴보자.

AJAX를 사용한 구현

가끔 데이터는 메인 페이지에 로드되지 않고 AJAX를 통해 불러와져. 사이트가 이런 방식으로 작동하는 걸 발견하면, 브라우저의 네트워크 디버깅 툴을 사용해 백그라운드에서 어떤 요청이 이루어지는지 확인해야 해. 그런 다음 Python으로 이 요청을 재현해.

Python

# AJAX 호출 예제
ajax_url = 'http://example.com/ajax_endpoint'

params = {
'some_param': 'value',  # 요청에 필요한 매개변수
'page': 1
}

while True:
response = session.get(ajax_url, params=params)
data = response.json()
if not data['has_more']:
break
# 데이터 처리
for item in data['items']:
print(item)
params['page'] += 1  # 다음 페이지로 이동

이 접근법은 요청과 응답을 상세히 분석한 후 데이터가 브라우저에 로드되는 방식을 이해하게 되면 유용해.

오늘 강의는 매력적이고 종종 까다로운 pagination의 세계로 우리를 안내했어. 이 기술은 사이트에서 데이터를 효율적으로 수집하고 어떤 페이지도 놓치지 않도록 하는 데 도움이 돼. 결국, 웹 스크레이핑에서 중요한 건 꾸준함과 철저함이야. 누가 알겠어? 20번째 페이지에 숨겨진 보물이 있을지!

코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION