본문 바로가기

내일배움캠프

웹개발 4주차 과제 - 멜론 차트 스크래핑하기

그동안 웹개발 강의의 복습을 잘 해왔는지 확인할 수 있는 순간이 왔다. 지난번에 제대로 구현하지 못했던 flask를 이번에는 제대로 활용할 수 있는지 확인해보자!

메인페이지(index.html)

 

이 메인페이지에 멜론차트에서 스크래핑 해온 음악들을 넣어주면 된다.

from flask import Flask, render_template
from bs4 import BeautifulSoup
import requests

app = Flask(__name__)

@app.route('/')
def index():
    
    return render_template('index.html', data = melon_data)

if __name__ == '__main__':
    app.run()

 

app.py가 이미 index.html과 연결되어 있는 상태이다. 이제 멜론에서 데이터를 스크래핑 해오자.

 

멜론 TOP100 페이지와 개발자도구페이지

 

페이지를 열어보니 차트에 대한 데이터가 <tbody>안에 있는 <tr>별로 적혀있는 것을 알 수 있었다.

 

URL = 'https://www.melon.com/chart/index.htm'
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get(URL, headers=headers)
    soup = BeautifulSoup(data.text, 'html.parser')
    
    trs = soup.select('tbody > tr')

 

스크래핑할 페이지를 URL이라고 지정해둔다. 그리고 헤더와 함께 해당 페이지에 데이터를 요청해서 data변수에 저장한다.

저장한 데이터는 html.parser로 해석해서 data.text 형태로 바꾼 뒤 soup 변수에 저장한다.

soup에서 tbody안에 있는 tr을 모두 선택해서 trs에 저장한다.

 

melon_data = []
    
    for tr in trs:
        rank = tr.select_one('.rank').text
        title = tr.select_one('.rank01 > span > a').text
        artist = tr.select_one('.rank02 > a').text
        image = tr.select_one('img')['src']
        melon_data.append({'rank': rank, 'artist': artist, 'title': title, 'image': image})

 

melon_data라는 리스트를 생성하고 필요한 데이터들을 for반복문을 이용해서 순회하여 순서대로 입력한다.

각각 순위, 제목, 가수, 이미지파일이며 각 tr에서 해당 데이터의 위치를 찾아서 텍스트의 형태로 반환한다.

 

@app.route('/')
def index():
    URL = 'https://www.melon.com/chart/index.htm'
    headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36'}
    data = requests.get(URL, headers=headers)
    soup = BeautifulSoup(data.text, 'html.parser')
    
    trs = soup.select('tbody > tr')
    
    melon_data = []
    
    for tr in trs:
        rank = tr.select_one('.rank').text
        title = tr.select_one('.rank01 > span > a').text
        artist = tr.select_one('.rank02 > a').text
        image = tr.select_one('img')['src']
        melon_data.append({'rank': rank, 'artist': artist, 'title': title, 'image': image})
    
    return render_template('index.html', data = melon_data)

 

이제 멜론 페이지에서 데이터들을 스크래핑하고 필요한 데이터를 추출했다.

 

melon_data 리스트를 index.html로 data라는 이름으로 넘겨주자.

 

<div class="row row-cols-1 row-cols-md-4 g-4 mx-auto w-75 pb-5">
        {% for melon in data %}
        <div class="col">
            <div class="card h-100">
                <img src={{ melon.image }} class="card-img-top" alt="...">
                <div class="card-body">
                    <h5 class="card-title">{{ melon.title }}</h5>
                    <p class="card-text">{{ melon.artist }}</p>
                    <p class="card-text">추천 by 서재일</p> 
                </div>
            </div>
        </div>
        {% endfor %}
    </div>

 

index.html의 body의 해당 부분에서 음악 카드를 추가해줄 수 있다. 파이썬의 for반복문 형태로 받아온 데이터를 해당 위치에 카드로 추가하게 된다.

 

index.html

 

과제 작성은 성공했지만 내가 제대로 잘 했는지는 모르겠다...

분명 작성은 완료했지만 뭔가 부족하다는 느낌이 많이 든다. 다른 비슷한 과제가 나왔을 때, 내가 이걸 풀 수 있을까? 아직 잘 모르겠다.

 

내일(금요일) 동안은 팀과제에 집중할 예정이다. 웹개발 강의는 주말중에 5강까지 들어보고 다시 복습을 해볼 것이다. 그때는 코드의 뼈대부터 작성을 해봐야겠다.