3-1. 크롤링한 데이터를 리스트화 List [], 사전화 Dict {}

2018. 5. 27. 14:34Coding/Python

728x90

1. '1위' (str)을 1 (int)로 바꾸기

데이터의 활용성을 높이기 위해서 의미없이 반복되는 '1위' '2위' '3위'.... 에서 순위를 나타내는 '위'를 없애고 숫자만 남게 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import requests
from bs4 import BeautifulSoup as BS
 
def mnet_Crawling(html):
    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
        rank = int(rank.strip('위'))
 
        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)
 
#============================================================ End of mnet_Crawling() ============================================================#
 
req = requests.get('http://www.mnet.com/chart/TOP100/')
 
for page in [1,2]:
    req = requests.get('http://www.mnet.com/chart/TOP100/?pNum={}'.format(page))
    html = BS(req.text, 'html.parser')
    
    mnet_Crawling(html)
 
 
 
cs

1 http://cmsimg.mnet.com/clipimage/album/50/002/949/2949825.jpg 여행 볼빨간사춘기 Red Diary Page.2

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

...

...

99 http://cmsimg.mnet.com/clipimage/album/50/002/398/2398758.jpg Beautiful Wanna One(워너원) 1-1=0 (NOTHING WITHOUT YOU)

100 http://cmsimg.mnet.com/clipimage/album/50/002/399/2399185.jpg 좋아 민서 2017 월간 윤종신 11월호


rank가 int형으로 바뀌었습니다.

rank = tr.find('td',{'class':'MMLItemRank'}).find('span').text

rank = int(rank.strip('위'))

위 두줄을 아래처럼 한줄로도 표현 가능합니다.

rank = int(tr.find('td',{'class':'MMLItemRank'}).find('span').text.strip('위'))






2. 리스트 만들기 List []

이전까지는 추출한 데이터를 바로 출력했습니다.

이를 리스트로 만들어서 데이터를 활용할 수 있게 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import requests
from bs4 import BeautifulSoup as BS
 
def mnet_Crawling(html):
    temp_list = []
 
    tr_list = html.select('div.MnetMusicList.MnetMusicListChart > div.MMLTable.jQMMLTable > table > tbody > tr')
 
    for tr in tr_list :
        rank = int(tr.find('td',{'class':'MMLItemRank'}).find('span').text.strip('위'))
 
        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
        temp_list.append([rank, img, title, artist, album])
 
 
 
    return temp_list
#============================================================ End of mnet_Crawling() ============================================================#
 
mnet_list = []
 
req = requests.get('http://www.mnet.com/chart/TOP100/')
 
for page in [1,2]:
    req = requests.get('http://www.mnet.com/chart/TOP100/?pNum={}'.format(page))
    html = BS(req.text, 'html.parser')
    
    mnet_list += mnet_Crawling(html)
 
 
# 리스트 출력
for item in mnet_list :
    print(item)
 
 
cs

[1, 'http://cmsimg.mnet.com/clipimage/album/50/002/949/2949825.jpg', '여행', '볼빨간사춘기', 'Red Diary Page.2']

[2, 'http://cmsimg.mnet.com/clipimage/album/50/002/939/2939994.jpg', 'FAKE LOVE', '방탄소년단', 'LOVE YOURSELF 轉 `Tear`']

...

...

...

[99, 'http://cmsimg.mnet.com/clipimage/album/50/002/398/2398758.jpg', 'Beautiful', 'Wanna One(워너원)', '1-1=0 (NOTHING WITHOUT YOU)']

[100, 'http://cmsimg.mnet.com/clipimage/album/50/002/399/2399185.jpg', '좋아', '민서', '2017 월간 윤종신 11월호']


mnet_Crawling()함수에 temp_list[] 임시 리스트를 선언하고, .append()함수로 temp_list[] 임시 리스트에 추가를 해준다.

단, 이렇게만 하면 페이지가 2개이기 때문에 반환 받을때 1페이지 위에 2페이지가 덧씌워지기 때문에

mnet_list = mnet_Crawling(html)    => X

mnet_list += mnet_Crawling(html)    => O

이렇게 mnet_list = mnet_list + mnet_Crawling(html) 기존 리스트(1페이지)에 새로운 리스트(2페이지)를 해준다.






3. 사전형 만들기 Dict {}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import requests
from bs4 import BeautifulSoup as BS
 
def mnet_Crawling(html):
    temp_dict = {}
 
    tr_list = html.select('div.MnetMusicList.MnetMusicListChart > div.MMLTable.jQMMLTable > table > tbody > tr')
 
    for tr in tr_list :
        rank = int(tr.find('td',{'class':'MMLItemRank'}).find('span').text.strip('위'))
 
        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
        temp_dict[str(rank)] = {'img':img, 'title':title, 'artist':artist, 'album':album}
 
 
 
    return temp_dict
#============================================================ End of mnet_Crawling() ============================================================#
 
mnet_dict = {}
 
req = requests.get('http://www.mnet.com/chart/TOP100/')
 
for page in [1,2]:
    req = requests.get('http://www.mnet.com/chart/TOP100/?pNum={}'.format(page))
    html = BS(req.text, 'html.parser')
    
    mnet_dict = dict(mnet_dict, **mnet_Crawling(html))
 
 
# 사전형 출력
for item in mnet_dict :
    print(item, mnet_dict[item]['img'], mnet_dict[item]['title'], mnet_dict[item]['artist'], mnet_dict[item]['album'])
cs

1 http://cmsimg.mnet.com/clipimage/album/50/002/949/2949825.jpg 여행 볼빨간사춘기 Red Diary Page.2

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

...

...

...

99 http://cmsimg.mnet.com/clipimage/album/50/002/398/2398758.jpg Beautiful Wanna One(워너원) 1-1=0 (NOTHING WITHOUT YOU)

100 http://cmsimg.mnet.com/clipimage/album/50/002/399/2399185.jpg 좋아 민서 2017 월간 윤종신 11월호


temp_dict[key0] = {'key1':value1, 'key2':value2, 'key3':value3, 'key4':value4 ... } rank를 '해당 순위의 정보' 키값으로 추가 합니다.

기껏 '1. '1위' (str)을 1 (int)로 바꾸기'에서 정수형으로 바꾸었지만,

TypeError: keyword arguments must be strings

에러가 떠서 어쩔수 없이 str형으로 바꾸었습니다...ㅠ


위의 List 때, List = 1Page_List + 2Page_List 한 것 처럼,

사전형도 Dict = 1Page_Dict + 2Page_Dict를 해줘야 합니다. 

List처럼 더하기로 간단하게는 안되고, dict(dict1, **dict2) 함수를 이용합니다. 

mnet_dict = dict(mnet_dict, **mnet_Crawling(html))






4. List [] 와 Dict {} 같이 return 받기

앞서 진행한 '2. 리스트 만들기 List []' , '3. 사전형 만들기 Dict {}'는 각각 진행하여 mnet_Crawling()함수에서 1개의 List혹은 Dict만 return 받았습니다.

두가지를 한번에 처리하는 방법을 알아봅니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import requests
from bs4 import BeautifulSoup as BS
 
def mnet_Crawling(html):
    temp_list = []
    temp_dict = {}
 
    tr_list = html.select('div.MnetMusicList.MnetMusicListChart > div.MMLTable.jQMMLTable > table > tbody > tr')
 
    for tr in tr_list :
        rank = int(tr.find('td',{'class':'MMLItemRank'}).find('span').text.strip('위'))
 
        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
        temp_list.append([rank, img, title, artist, album])
        temp_dict[str(rank)] = {'img':img, 'title':title, 'artist':artist, 'album':album}
 
 
 
    return temp_list, temp_dict
#============================================================ End of mnet_Crawling() ============================================================#
 
mnet_list = []
mnet_dict = {}
 
req = requests.get('http://www.mnet.com/chart/TOP100/')
 
for page in [1,2]:
    req = requests.get('http://www.mnet.com/chart/TOP100/?pNum={}'.format(page))
    html = BS(req.text, 'html.parser')
    
    mnet_temp = mnet_Crawling(html)
    mnet_list += mnet_temp[0]
    mnet_dict = dict(mnet_dict, **mnet_temp[1])
 
# 리스트 출력
for item in mnet_list :
    print(item)
 
# 사전형 출력
for item in mnet_dict :
    print(item, mnet_dict[item]['img'], mnet_dict[item]['title'], mnet_dict[item]['artist'], mnet_dict[item]['album'])
 
 
cs

[1, 'http://cmsimg.mnet.com/clipimage/album/50/002/949/2949825.jpg', '여행', '볼빨간사춘기', 'Red Diary Page.2']

[2, 'http://cmsimg.mnet.com/clipimage/album/50/002/939/2939994.jpg', 'FAKE LOVE', '방탄소년단', 'LOVE YOURSELF 轉 `Tear`']

...

...

...

[99, 'http://cmsimg.mnet.com/clipimage/album/50/002/215/2215013.jpg', '그리워하다', '비투비(BTOB)', 'Brother Act.']

[100, 'http://cmsimg.mnet.com/clipimage/album/50/002/398/2398758.jpg', 'Beautiful', 'Wanna One(워너원)', '1-1=0 (NOTHING WITHOUT YOU)']

1 http://cmsimg.mnet.com/clipimage/album/50/002/949/2949825.jpg 여행 볼빨간사춘기 Red Diary Page.2

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

...

...

...

99 http://cmsimg.mnet.com/clipimage/album/50/002/215/2215013.jpg 그리워하다 비투비(BTOB) Brother Act.

100 http://cmsimg.mnet.com/clipimage/album/50/002/398/2398758.jpg Beautiful Wanna One(워너원) 1-1=0 (NOTHING WITHOUT YOU)


return temp_list, temp_dict List와 Dict를 같이 return받아서 mnet_temp = mnet_Crawling(html) 

 임시로 데이터를 보관할 mnet_temp에 넣으면 Tuple () 형태로 List와 Dict가 저장이 됩니다.

간단하게 보면

( [], {} )

이런식 입니다.


결국

mnet_temp[0] = temp_list

mnet_temp[1] = temp_dict

이런 구조임을 알 수 있습니다.


그러므로

mnet_temp = mnet_Crawling(html)
mnet_list += mnet_temp[0]
mnet_dict = dict(mnet_dict, **mnet_temp[1])

mnet_temp에 페이지별 List와 Dict를 임시 저장하고,

mnet_list와 mnet_dict에 나눠서 추가해줍니다.


몇가지 추가된거 말고는 위에서 진행한 방식과 같습니다.



728x90