지니뮤직 1~50 순위 크롤링 하기

이은주·2022년 2월 25일
1

웹 개발일지

목록 보기
7/7

1. 파이썬 패키지

1-1. 패키지란?

Python 에서 패키지는 모듈(일종의 기능들 묶음)을 모아 놓은 단위이다. 이런 패키지 의 묶음을 라이브러리 라고 볼 수 있다. 즉 외부 라이브러리를 사용하기 위해서 패키지를 설치해야 한다.

1-2. request 라이브러리

1) request

request는 파이썬으로 HTTP 호출하는 프로그램을 작성할 때 가장 많이 사용되는 라이브러리이다. HTTP, HTTPS 웹 사이트에 요청하기 위해 사용되는 모듈 중 하나이다.

GET 방식: request.get()
POST 방식: request.post()

2) 사용방법

import requests							# request 라이브러리 불러오기
data = requests.get('요청 할 url 입력')	# 특정 변수에 get 방식으로 데이터 가져오기

3) 헤더 값 추가

User-Agent 값이 없으면 서버에서 응답 값을 내주지 않는 경우가 있다. 이 경우 HTTP 요청에 headers 값을 추가해야 한다.

크롬 User-Agent 값 확인하기

  1. 크롬 개발자 도구[단축키 F12] 들어가기
  2. Console 창에 navigator.userAgent 입력
    → 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'

헤더 값 추가하기

import requests
headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'}
data = requests.get('요청 할 url 입력',headers=headers)

1-3. bs4 라이브러리

1) bs4(BeautifulSoup4)

bs4란 웹에서 가져온 HTML 코드를 파이썬에서 사용하기 편하게 비슷한 분류의 데이터별로 나누어주는 라이브러리이다.

2) 사용방법

import requests									# requests 불러오기
from bs4 import BeautifulSoup					# bs4에 있는 BeatifulSoup 불러오기

data = requests.get('요청 할 url 입력')			# requests 사용
soup = BeatifulSoup(data.text,'html.parser')	# BeatifulSoup	사용
- data.text : data로 얻은 html을 문자열로 반환하는 것을 의미
- 'html.parser' : 기본적으로 내장되어 있는 분류 방식(parser) 사용
→ 이 외에도 lxml, xml 등의 분류 방식이 있음

2. 파이썬 패키지 설치하기

  1. 파일 > 설정 > +
  2. requests 검색 > 패키지 설치
  3. 같은 방법으로 bs4 설치

3. 지니 뮤직 크롤링 하기

아래와 같이 나오도록 지니 뮤직 크롤링 하기!

1 바라만 본다 MSG워너비 (M.O.M)
2 Next Level aespa
3 신호등 이무진
4 Weekend 태연 (TAEYEON)
5 치맛바람 (Chi Mat Ba Ram) 브레이브걸스 (Brave girls)
6 Butter 방탄소년단
7 나를 아는 사람 MSG워너비 (정상동기)
8 Permission to Dance 방탄소년단
9 비 오는 날 듣기 좋은 노래 (Feat. Colde) 에픽하이 (EPIK HIGH)
10 헤픈 우연 헤이즈 (Heize)
11 하루만 더 빅마마 (Big Mama)
12 비와 당신 이무진
13 Alcohol-Free TWICE (트와이스)
14 롤린 (Rollin') 브레이브걸스 (Brave girls)
15 Peaches (Feat. Daniel Caesar & Giveon) Justin Bieber
16 Dun Dun Dance 오마이걸 (OH MY GIRL)
17 Dynamite 방탄소년단
18 라일락 아이유 (IU)
19 안녕 (Hello) 조이 (JOY)
20 추적이는 여름 비가 되어 장범준
21 운전만해 (We Ride) 브레이브걸스 (Brave girls)
22 Celebrity 아이유 (IU)
23 러브 (Prod. by 로코베리) 로꼬 & 이성경
24 Bad Habits Ed Sheeran
25 상상더하기 MSG워너비
26 ASAP STAYC (스테이씨)
27 상상더하기 라붐 (LABOUM)
28 밤이 되니까 원슈타인
29 Timeless SG워너비
30 좋아좋아 조정석
31 Savage Love (Laxed - Siren Beat) (BTS Remix) Jawsh 685 & Jason Derulo & 방탄소년단
32 다정히 내 이름을 부르면 경서예지 & 전건호
33 내 손을 잡아 아이유 (IU)
34 사이렌 Remix (Feat. UNEDUCATED KID & Paul Blanco) 호미들
35 At My Worst Pink Sweat$
36 작은 것들을 위한 시 (Boy With Luv) (Feat. Halsey) 방탄소년단
37 OHAYO MY NIGHT 디핵 (D-Hack) & PATEKO
38 가을 우체국 앞에서 김대명
39 나는 너 좋아 장범준
40 멜로디 ASH ISLAND
41 Blueming 아이유 (IU)
42 밝게 빛나는 별이 되어 비춰줄게 송이한
43 에잇 (Prod. & Feat. SUGA of BTS) 아이유 (IU)
44 2002 Anne-Marie
45 LOVE DAY (2021) (바른연애 길잡이 X 양요섭, 정은지) 양요섭 & 정은지
46 아로하 조정석
47 흔들리는 꽃들 속에서 네 샴푸향이 느껴진거야 장범준
48 이제 나만 믿어요 임영웅
49 낙하 (With 아이유) AKMU (악뮤)
50 Off My Face Justin Bieber

3-1. 크롤링 기본 셋팅

1. request 라이브러리 셋팅

# 1) requests 라이브러리 import
import requests

# 2) headers란 변수에 User-Agent 값 넣기
headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'}

# 3) url을 이용해 get 방식으로 HTML 문서 요청
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

2. bs4 라이브러리 셋팅

import requests

# 1) bs4 에서 BeautifulSoup 불러오기
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

# 2-1) data에서 받은 HTML 문서를 text(문자열) 형식으로 반환해서 
# 2-2) 파이썬이 읽을 수 있는 태그 기반 html 구조로 변환
soup = BeautifulSoup(data.text, 'html.parser')

3-2. 가져올 데이터 위치 파악

1. rank

1) 개발자 도구 → 아래 그림에서 1번 누르기 → 순위가 적혀 있는 부분 클릭

2) 개발자 도구 Elements 에 표시된 줄 더블 클릭 → Copy → Copy selector

3) 같은 방식으로 2순위 부분도 Copy selector
4) 순위 위치 파악

rank 1 selector: #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.number
rank 2 selector: #body-content > div.newest-list > div > table > tbody > tr:nth-child(2) > td.number

2. title

위와 같은 방법으로 2개의 노래 제목 Copy selector

rank 1 selector: #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.info > a.title.ellipsis
rank 2 selector: #body-content > div.newest-list > div > table > tbody > tr:nth-child(2) > td.info > a.title.ellipsis

3. artist

2개의 노래 가수 Copy selector

rank 1 selector: #body-content > div.newest-list > div > table > tbody > tr:nth-child(1) > td.info > a.artist.ellipsis
rank 2 selector: #body-content > div.newest-list > div > table > tbody > tr:nth-child(2) > td.info > a.artist.ellipsis

4. 태그 파악

rank, title, artist 모두 아래 태그까지 동일

#body-content > div.newest-list > div > table > tbody > tr

3-3. 데이터 선택해서 가져오기

1. 필요한 데이터 선택해서 가져오기

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

# trs 라는 변수에 아래 경로에 있는 모든 tr 태그 안에 있는 정보 가져오기
trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')
trs에는 다음과 같이 리스트 형식으로 저장한다.

trs[0]에는 tr:nth-child(1)에 포함되는 정보를,
trs[1]에는 tr:nth-child(2)에 포함되는 정보를,
trs[2]에는 tr:nth-child(3)에 포함되는 정보를,
trs[3]에는 tr:nth-child(4)에 포함되는 정보를,
...
trs[49]에는 tr:nth-child(50)에 포함되는 정보를 저장한다.

2. 반복문을 이용해 rank, title, artist 데이터 선택하기

trs은 trs[0]~trs[49]까지 총 50개의 요소가 저장된 리스트 이므로 반복문을 사용해 필요한 정보를 선택해 가져올 수 있다.

- rank 위치: tr > td.number
- title 위치: tr > td.info > a.title.ellipsis
- artist 위치: tr > td.info > a.artist.ellipsis
import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')

# trs[0]부터 trs[49]까지 순서대로 돌면서
for tr in trs:
	# 클래스명이 number인 td태그의 text를 변수 rank에 담는다.
    rank = tr.select_one('td.number').text
    # a.title.ellipsis에 위치한 text를 변수 title에 담는다.
    title = tr.select_one('a.title.ellipsis').text
    # a.artist.ellipsis에 위치한 text를 변수 artist에 담는다.
    artist = tr.select_one('a.artist.ellipsis').text

3-4. 데이터 출력하기

1. 출력 해 보기

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')

# trs[0]부터 trs[49]까지 순서대로 돌면서
for tr in trs:
    rank = tr.select_one('td.number').text
    title = tr.select_one('a.title.ellipsis').text
    artist = tr.select_one('a.artist.ellipsis').text
	
    # rank, title, artist 출력
    print(rank, title, artist)
1
                                        
                                    
20상승

 
                                            
                                            
                                            
                                            
                                        
                                        
                                    
                                    바라만 본다 MSG워너비 (M.O.M)
2
                                        
                                    
유지

 
                                            
                                            
                                            
                                            
                                        
                                        
                                    
                                    Next Level aespa
                                    
...

50
                                        
                                    
13하강

 
                                            
                                            
                                            
                                            
                                        
                                        
                                    
                                    Off My Face Justin Bieber

2. rank, title 여백 제거

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')

for tr in trs:
    rank = tr.select_one('td.number').text.strip()
    title = tr.select_one('a.title.ellipsis').text.strip()
    artist = tr.select_one('a.artist.ellipsis').text

    print(rank, title, artist)
1
                                        
                                    
20상승 바라만 본다 MSG워너비 (M.O.M)
2
                                        
                                    
유지 Next Level aespa

...

50
                                        
                                    
13하강 Off My Face Justin Bieber

3. rank 순위만 출력

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')

for tr in trs:
    rank = tr.select_one('td.number').text[0:2].strip()
    title = tr.select_one('a.title.ellipsis').text.strip()
    artist = tr.select_one('a.artist.ellipsis').text

    print(rank, title, artist)
1 바라만 본다 MSG워너비 (M.O.M)
2 Next Level aespa
3 신호등 이무진
4 Weekend 태연 (TAEYEON)
5 치맛바람 (Chi Mat Ba Ram) 브레이브걸스 (Brave girls)
6 Butter 방탄소년단
7 나를 아는 사람 MSG워너비 (정상동기)
8 Permission to Dance 방탄소년단
9 비 오는 날 듣기 좋은 노래 (Feat. Colde) 에픽하이 (EPIK HIGH)
10 헤픈 우연 헤이즈 (Heize)
11 하루만 더 빅마마 (Big Mama)
12 비와 당신 이무진
13 Alcohol-Free TWICE (트와이스)
14 롤린 (Rollin') 브레이브걸스 (Brave girls)
15 19금
                                            
                                        
                                        
                                    
                                    Peaches (Feat. Daniel Caesar & Giveon) Justin Bieber
16 Dun Dun Dance 오마이걸 (OH MY GIRL)
17 Dynamite 방탄소년단
18 라일락 아이유 (IU)
19 안녕 (Hello) 조이 (JOY)
20 추적이는 여름 비가 되어 장범준
21 운전만해 (We Ride) 브레이브걸스 (Brave girls)
22 Celebrity 아이유 (IU)
23 러브 (Prod. by 로코베리) 로꼬 & 이성경
24 Bad Habits Ed Sheeran
25 상상더하기 MSG워너비
26 ASAP STAYC (스테이씨)
27 상상더하기 라붐 (LABOUM)
28 밤이 되니까 원슈타인
29 Timeless SG워너비
30 좋아좋아 조정석
31 Savage Love (Laxed - Siren Beat) (BTS Remix) Jawsh 685 & Jason Derulo & 방탄소년단
32 다정히 내 이름을 부르면 경서예지 & 전건호
33 내 손을 잡아 아이유 (IU)
34 사이렌 Remix (Feat. UNEDUCATED KID & Paul Blanco) 호미들
35 At My Worst Pink Sweat$
36 작은 것들을 위한 시 (Boy With Luv) (Feat. Halsey) 방탄소년단
37 OHAYO MY NIGHT 디핵 (D-Hack) & PATEKO
38 가을 우체국 앞에서 김대명
39 나는 너 좋아 장범준
40 멜로디 ASH ISLAND
41 Blueming 아이유 (IU)
42 밝게 빛나는 별이 되어 비춰줄게 송이한
43 에잇 (Prod. & Feat. SUGA of BTS) 아이유 (IU)
44 2002 Anne-Marie
45 LOVE DAY (2021) (바른연애 길잡이 X 양요섭, 정은지) 양요섭 & 정은지
46 아로하 조정석
47 흔들리는 꽃들 속에서 네 샴푸향이 느껴진거야 장범준
48 이제 나만 믿어요 임영웅
49 낙하 (With 아이유) AKMU (악뮤)
50 Off My Face Justin Bieber

4. title에 "19금" 문자열 지우기

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')

for tr in trs:
    rank = tr.select_one('td.number').text[0:2].strip()

    title = tr.select_one('a.title.ellipsis').text.strip()
	
    # 만약 title에 "19금" 문자열이 있다면
    if "19금" in title:
    	# "19금" 문자열 지우고
        title = title.strip("19금")
        # title 양쪽 여백 지우기
        title = title.strip()

    artist = tr.select_one('a.artist.ellipsis').text

    print(rank, title, artist)

최종 코드

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/98.0.4758.102 Safari/537.36'}
data = requests.get('https://www.genie.co.kr/chart/top200?ditc=M&rtm=N&ymd=20210701',headers=headers)

soup = BeautifulSoup(data.text, 'html.parser')

trs = soup.select('#body-content > div.newest-list > div > table > tbody > tr')

for tr in trs:
    rank = tr.select_one('td.number').text[0:2].strip()

    title = tr.select_one('a.title.ellipsis').text.strip()

    if "19금" in title:
        title = title.strip("19금")
        title = title.strip()

    artist = tr.select_one('a.artist.ellipsis').text

    print(rank, title, artist)

실행 결과

1 바라만 본다 MSG워너비 (M.O.M)
2 Next Level aespa
3 신호등 이무진
4 Weekend 태연 (TAEYEON)
5 치맛바람 (Chi Mat Ba Ram) 브레이브걸스 (Brave girls)
6 Butter 방탄소년단
7 나를 아는 사람 MSG워너비 (정상동기)
8 Permission to Dance 방탄소년단
9 비 오는 날 듣기 좋은 노래 (Feat. Colde) 에픽하이 (EPIK HIGH)
10 헤픈 우연 헤이즈 (Heize)
11 하루만 더 빅마마 (Big Mama)
12 비와 당신 이무진
13 Alcohol-Free TWICE (트와이스)
14 롤린 (Rollin') 브레이브걸스 (Brave girls)
15 Peaches (Feat. Daniel Caesar & Giveon) Justin Bieber
16 Dun Dun Dance 오마이걸 (OH MY GIRL)
17 Dynamite 방탄소년단
18 라일락 아이유 (IU)
19 안녕 (Hello) 조이 (JOY)
20 추적이는 여름 비가 되어 장범준
21 운전만해 (We Ride) 브레이브걸스 (Brave girls)
22 Celebrity 아이유 (IU)
23 러브 (Prod. by 로코베리) 로꼬 & 이성경
24 Bad Habits Ed Sheeran
25 상상더하기 MSG워너비
26 ASAP STAYC (스테이씨)
27 상상더하기 라붐 (LABOUM)
28 밤이 되니까 원슈타인
29 Timeless SG워너비
30 좋아좋아 조정석
31 Savage Love (Laxed - Siren Beat) (BTS Remix) Jawsh 685 & Jason Derulo & 방탄소년단
32 다정히 내 이름을 부르면 경서예지 & 전건호
33 내 손을 잡아 아이유 (IU)
34 사이렌 Remix (Feat. UNEDUCATED KID & Paul Blanco) 호미들
35 At My Worst Pink Sweat$
36 작은 것들을 위한 시 (Boy With Luv) (Feat. Halsey) 방탄소년단
37 OHAYO MY NIGHT 디핵 (D-Hack) & PATEKO
38 가을 우체국 앞에서 김대명
39 나는 너 좋아 장범준
40 멜로디 ASH ISLAND
41 Blueming 아이유 (IU)
42 밝게 빛나는 별이 되어 비춰줄게 송이한
43 에잇 (Prod. & Feat. SUGA of BTS) 아이유 (IU)
44 2002 Anne-Marie
45 LOVE DAY (2021) (바른연애 길잡이 X 양요섭, 정은지) 양요섭 & 정은지
46 아로하 조정석
47 흔들리는 꽃들 속에서 네 샴푸향이 느껴진거야 장범준
48 이제 나만 믿어요 임영웅
49 낙하 (With 아이유) AKMU (악뮤)
50 Off My Face Justin Bieber

3개의 댓글

comment-user-thumbnail
2022년 5월 3일
  1. rank에 순위만 출력 부분에서 for문 rank 텍스트 옆에 [0:2] 가 들어가는 의미는 뭔가요?!
1개의 답글
comment-user-thumbnail
2022년 11월 21일

하루종일 해맸는데 고맙습니다.ㅠ.,ㅠ

답글 달기