Chapter 3-4 Web Scraping 과제 (멜론차트 Top100 1위부터 100위까지)

2025. 4. 16. 10:31·웹스크래핑과 데이터 수집

최종 코드

from selenium import webdriver
from bs4 import BeautifulSoup
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
import time

# 모바일 사용자 에이전트 설정
user = "Mozilla/5.0 (IPhone; CPU iPhone OS 13_3 like Mac OS X) AppleWebKit/605.1.15(KHTML, like Gecko) CriOS/80.0.3987.95 Mobile/15E148 Safari/604.1"

# 크롬 옵션 설정
options_ = Options()
options_.add_argument(f"user-agent={user}")
options_.add_experimental_option("detach", True)  # 드라이버가 종료되지 않도록 설정
options_.add_experimental_option("excludeSwitches", ["enable-logging"])

# 크롬 드라이버 매니저 자동 설치
service = Service(ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=options_)

url = "https://m2.melon.com/index.htm"
driver.get(url)
time.sleep(0.5)

# 페이지가 제대로 로딩되지 않은 경우, 메인 화면으로 이동
if driver.current_url != url:
    driver.get(url)

# '멜론차트' 버튼 클릭
driver.find_element(By.LINK_TEXT, "멜론차트").click()
time.sleep(0.5)

# 51위부터 100위까지 보이게 하기 위해 '더보기' 버튼 클릭
driver.find_elements(By.CSS_SELECTOR, "#moreBtn")[1].click()
time.sleep(0.5)

# 페이지 소스 가져오기
html = driver.page_source
soup = BeautifulSoup(html, "html.parser")

# 차트 목록에서 각 노래 정보를 추출
items = soup.select("#_chartList .list_item")

# 노래 순위, 제목, 가수 출력
for i in items:
    rank = i.select_one(".ranking_num")  # 순위
    title = i.select_one(".title.ellipsis")  # 노래 제목
    singer = i.select_one(".name.ellipsis")  # 가수

    print(f"순위 : {rank.text.strip()}")
    print(f"제목 : {title.text.strip()}")
    print(f"가수 : {singer.text.strip()}")
    print()

# 드라이버 종료
driver.quit()

📌 개념 정리

이번 과제는 Selenium을 사용하여 멜론 모바일 사이트의 Top100 차트 정보를 스크래핑하는 작업입니다. 이 과제를 통해 Selenium을 활용한 동적 웹 페이지에서 데이터를 추출하는 방법을 배울 수 있습니다. 특히 모바일 버전 페이지로 접속하고, '더보기' 버튼을 클릭하여 추가 순위를 로드한 후, 순위, 제목, 가수 등의 정보를 추출합니다.


🚦 동작 원리 및 구조

  1. Selenium WebDriver 설정:
    Selenium WebDriver를 사용하여 Chrome 브라우저를 실행하고, 모바일 웹사이트를 로드합니다. Options()을 통해 모바일 버전의 사용자 에이전트를 설정하여 모바일 사이트를 로드합니다.
  2. 페이지 로드 및 '멜론차트' 버튼 클릭:
    사이트가 제대로 로드되지 않은 경우, 페이지 URL을 확인하고, '멜론차트' 메뉴를 클릭하여 차트 페이지로 이동합니다.
  3. '더보기' 버튼 클릭:
    멜론차트 페이지에서 처음 50위까지만 표시되므로, '더보기' 버튼을 클릭하여 51위부터 100위까지 순위가 추가로 로드되도록 합니다. 버튼은 동일한 클래스명을 가진 여러 개가 존재하므로 인덱스를 활용하여 정확히 클릭합니다.
  4. 페이지 소스 가져오기 및 파싱:
    Selenium으로 로드된 페이지에서 **driver.page_source**를 사용하여 HTML을 가져오고, **BeautifulSoup**을 사용하여 HTML을 파싱하여 원하는 정보를 추출합니다.
  5. 노래 순위, 제목, 가수 추출:
    차트 목록에서 순위, 노래 제목, 가수 이름을 CSS 선택자를 사용하여 추출하고, 이를 출력합니다.

💻 코드 예시 및 흐름 분석

1. 웹 드라이버 설정 및 모바일 사이트 접속

options_ = Options()
options_.add_argument(f"user-agent={user}")
driver = webdriver.Chrome(service=service, options=options_)
url = "https://m2.melon.com/index.htm"
driver.get(url)

설명:
Selenium을 사용하여 Chrome 브라우저를 실행하고, 모바일 버전 사이트로 접속합니다. user-agent를 설정하여 모바일 버전 페이지를 로드합니다.

2. '멜론차트' 클릭 및 '더보기' 버튼 클릭

driver.find_element(By.LINK_TEXT, "멜론차트").click()
driver.find_elements(By.CSS_SELECTOR, "#moreBtn")[1].click()

설명:
'멜론차트' 버튼을 클릭하여 차트 페이지로 이동하고, '더보기' 버튼을 클릭하여 51위부터 100위까지의 추가 정보를 로드합니다.

3. HTML 소스 추출 및 파싱

html = driver.page_source
soup = BeautifulSoup(html, "html.parser")

설명:
페이지가 완전히 로드된 후, driver.page_source로 HTML을 가져와 BeautifulSoup을 사용해 파싱합니다.

4. 차트 정보 추출 및 출력

items = soup.select("#_chartList .list_item")
for i in items:
    rank = i.select_one(".ranking_num")
    title = i.select_one(".title.ellipsis")
    singer = i.select_one(".name.ellipsis")

    print(f"순위 : {rank.text.strip()}")
    print(f"제목 : {title.text.strip()}")
    print(f"가수 : {singer.text.strip()}")

설명:
차트 목록에서 각 노래에 대한 순위, 제목, 가수 정보를 추출하고 출력합니다. .strip()을 사용하여 불필요한 공백을 제거합니다.


🧪 실전 사례

예시 실행:

순위 : 1
제목 : Butter
가수 : 방탄소년단

순위 : 2
제목 : 롤린
가수 : 브레이브걸스

...

위와 같이 각 노래의 순위, 제목, 가수 정보를 출력할 수 있습니다.


🧠 고급 팁 or 자주 하는 실수

  • '더보기' 버튼 클릭 시 인덱스 문제:
    find_elements()를 사용할 때, 동일한 클래스명을 가진 버튼이 여러 개 존재할 수 있습니다. 이럴 경우, 인덱스를 정확히 지정하여 클릭해야 합니다.
  • 동적 로딩:
    페이지가 완전히 로드되지 않은 경우, 데이터를 추출하려고 할 때 비어 있는 데이터를 가져올 수 있습니다. time.sleep()으로 일정 시간 대기 후 데이터를 추출하거나, WebDriverWait을 사용하여 페이지가 로딩될 때까지 기다릴 수 있습니다.

✅ 마무리 요약 및 복습 포인트

  1. Selenium WebDriver: webdriver.Chrome()을 사용하여 브라우저를 실행하고, find_element()와 find_elements()를 활용하여 페이지의 특정 요소를 클릭하거나 추출합니다.
  2. 모바일 버전 페이지: 모바일 페이지로 접속하기 위해 user-agent를 설정하여 모바일 사이트로 로드합니다.
  3. 동적 로딩 처리: '더보기' 버튼을 클릭하여 페이지에 추가 데이터를 로드하고, 이를 추출하는 방법을 배웠습니다.

📚 복습할 개념 체크리스트

  • Selenium WebDriver: find_element(), find_elements()를 사용하여 웹 요소를 찾고 조작하는 방법.
  • 모바일 버전 웹사이트 접속: user-agent를 사용하여 모바일 웹사이트로 접속하는 방법.
  • 동적 페이지 로딩 처리: time.sleep() 또는 WebDriverWait을 사용하여 동적으로 로딩되는 페이지에서 데이터를 추출하는 방법.
  • BeautifulSoup: select()와 select_one()을 사용하여 HTML 요소에서 데이터를 추출하는 방법.

'웹스크래핑과 데이터 수집' 카테고리의 다른 글

Chapter 3-6 Tip 오류 해결  (0) 2025.04.16
Chapter 3-5 무료호스팅  (0) 2025.04.16
Chapter 3-3 Web Scraping 과제 (CGV 사이트에 있는 무비차트)  (0) 2025.04.16
Chapter 3-2 Web Scraping 과제 (find_all)  (0) 2025.04.16
Chapter 3-1 Web Scraping 과제 (광고 x)  (0) 2025.04.16
'웹스크래핑과 데이터 수집' 카테고리의 다른 글
  • Chapter 3-6 Tip 오류 해결
  • Chapter 3-5 무료호스팅
  • Chapter 3-3 Web Scraping 과제 (CGV 사이트에 있는 무비차트)
  • Chapter 3-2 Web Scraping 과제 (find_all)
Chansman
Chansman
안녕하세요! 코딩을 시작한 지 얼마 되지 않은 초보 개발자 찬스맨입니다. 이 블로그는 제 학습 기록을 남기고, 다양한 코딩 실습을 통해 성장하는 과정을 공유하려고 합니다. 초보자의 눈높이에 맞춘 실습과 팁, 그리고 개발하면서 겪은 어려움과 해결 과정을 솔직하게 풀어내려 합니다. 함께 성장하는 개발자 커뮤니티가 되기를 바랍니다.
  • Chansman
    찬스맨의 프로그래밍 스토리
    Chansman
  • 전체
    오늘
    어제
    • 분류 전체보기 (798)
      • Python (32)
      • 프로젝트 (113)
      • 과제 (25)
      • Database (40)
      • 멘토링 (11)
      • 특강 (37)
      • 기술블로그 (41)
      • 기술블로그-Fastapi편 (33)
      • 기술블로그-Django편 (154)
      • 기술블로그-Flask편 (36)
      • AI 분석 (5)
      • HTML & CSS (31)
      • JavaScript (17)
      • AWS_Cloud (21)
      • 웹스크래핑과 데이터 수집 (14)
      • Flask (42)
      • Django (77)
      • Fastapi (16)
      • 연예 (14)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    remittance
    lawsuitculture
    homebartrend
    life reflection
    urbantrends
    hotcoffeecase
    trumpmuskclash
    americaparty
    classaction
    travel ban
    newpoliticalparty
    smartphonedurability
    chatgpterror
    gpterror
    bts
    livebroadcast
    basalcellcarcinoma
    btsjungkook
    titaniumcase
    btsdischarge
    global politics
    college reunions
    youngprofessionals
    btscomeback
    RM
    btsreunion
    self-growth
    chinanightlife
    americanlaw
    뷔
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Chansman
Chapter 3-4 Web Scraping 과제 (멜론차트 Top100 1위부터 100위까지)
상단으로

티스토리툴바