2-3. BeautifulSoup를 이용한 Mnet 차트 크롤링 하기[데이터 접근]

2018. 5. 22. 18:26Coding/Python

728x90

1. 접근 방법

.find('태그')

.find_all('태그')

.select('태그주소')

.select_one('태그주소')

이렇게 네가지가 있고,


.find('태그') / .select_one('태그주소') 

태그나 태그주소를 통해 하나의 값을 반환합니다.

여러개일경우 최초 1개만 반환합니다.


.find_all('태그') / .select('태그주소')

태그나 태그주소를 통해 검색된 모든 결과를 List[] 목록으로 반환합니다.






2. tr_list 만들기


[2-1]에서 필요한 데이터들은 전부 각각 순위별 <tr>안에 <td>에 들어 있음을 알 수 있었습니다.

이를 이용하여 <tr>들을 List로 만들어서 

[

<tr>,

<tr>,

<tr>,

......

]

필요한 데이터(<td>)를 꺼내쓰면 됩니다.




1단계 - 접근하기 쉬운 유일값 찾기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import requests
from bs4 import BeautifulSoup as BS
 
req = requests.get('http://www.mnet.com/chart/TOP100/')
 
html = BS(req.text, 'html.parser')
 
 
tr_list1 = html.find_all('div',{'class':'MMLTable jQMMLTable'})
tr_list2 = html.find_all(class_='MMLTable jQMMLTable')
tr_list3 = html.select('div.MnetMusicList.MnetMusicListChart > div.MMLTable.jQMMLTable')
 
 
print(len(tr_list1))
print(len(tr_list2))
print(len(tr_list3))
cs

1

1

1


위처럼 find_all()이나, select()를 이용하여 검색을 했을때, 1개의 값만 출력되면 성공

0이 출력이되면 잘못 찾아간거고,

1이 출력이 되면 성공,

2이상이 출력이 되면 찾아가기가 함드니 좀 더 구분할 수 있는 키 포인트를 찾아야 합니다.

(위의 경우 구분을 하는 키 포인트로 div태그에 있는 class 값인 MMLTable jQMMLTable을 사용했습니다.

세가지 방식중, 상황에 맞게 사용하면 됩니다.




2단계 - <tr>에 접근하기

1
2
3
4
5
6
7
8
9
10
import requests
from bs4 import BeautifulSoup as BS
 
req = requests.get('http://www.mnet.com/chart/TOP100/')
 
html = BS(req.text, 'html.parser')
 
tr_list = html.select('div.MnetMusicList.MnetMusicListChart > div.MMLTable.jQMMLTable > table > tbody > tr')
 
print(len(tr_list))
cs

50

select()방법이 가장 간결해서 이를 이용했지만, 

tr_list = html.find('div', {'class':'MMLTable jQMMLTable'}).find('tbody').find_all('tr')

tr_list = html.find(class_ ='MMLTable jQMMLTable').find('tbody').find_all('tr')

모두 가능합니다.



현재 크롤링하는 페이지에 1 - 50위까지의 순위가 있으니, tr_list의 길이가 50이면 성공.

위처럼 len()을 안하고, print(tr_list)로 출력을 해보면, 

[

<tr>......</tr>,

<tr>......</tr>,

<tr>......</tr>,

...

]

위에서 언급한식의 tr_list가 완성된 것을 알 수 있습니다.






3. 데이터에 접근하기

tr_list를 만들었으니, for문으로 각 tr에 접근을 합니다.

접근 후 tr_list를 만들때와 같은 방식으로 필요한 데이터에 접근합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import requests
from bs4 import BeautifulSoup as BS
 
req = requests.get('http://www.mnet.com/chart/TOP100/')
 
html = BS(req.text, 'html.parser')
 
tr_list = html.select('div.MnetMusicList.MnetMusicListChart > div.MMLTable.jQMMLTable > table > tbody > tr')
 
for tr in tr_list :
    rank = tr.find('td',{'class':'MMLItemRank'}).find('span').text
 
    img = tr.find('td',{'class':'MMLItemTitle'}).find('div',{'class':'MMLITitle_Album'}).find('img')['src']
    img = tr.find('td',{'class':'MMLItemTitle'}).find('div',{'class':'MMLITitle_Album'}).find('img').get('src')
 
    title = tr.find('td',{'class':'MMLItemTitle'}).find('div',{'class':'MMLITitle_Box info'}).find('a',{'class':'MMLI_Song'}).text
    artist = tr.find('td',{'class':'MMLItemTitle'}).find('div',{'class':'MMLITitle_Box info'}).find('a',{'class':'MMLIInfo_Artist'}).text
    album = tr.find('td',{'class':'MMLItemTitle'}).find('div',{'class':'MMLITitle_Box info'}).find('a',{'class':'MMLIInfo_Album'}).text
    print(rank, img, title, artist, album)
 
cs

img의 경우 해당 src속성값에 접근하는 방법을 2가지로 나타내었습니다.

1위 http://cmsimg.mnet.com/clipimage/album/50/002/939/2939994.jpg FAKE LOVE 방탄소년단 LOVE YOURSELF 轉 `Tear`

2위 http://cmsimg.mnet.com/clipimage/album/50/002/904/2904091.jpg 밤 (Time for the moon night) 여자친구(GFRIEND) 여자친구 The 6th Mini Album `Time for the moon night`

...

...

...

49위 http://cmsimg.mnet.com/clipimage/album/50/001/754/1754473.jpg 첫눈처럼 너에게 가겠다 에일리 도깨비 OST Part 9

50위 http://cmsimg.mnet.com/clipimage/album/50/002/827/2827401.jpg BOOMERANG (부메랑) Wanna One(워너원) 0+1=1 (I PROMISE YOU)



728x90