2018. 5. 27. 14:34ㆍCoding/Python
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에 페이지별 List와 Dict를 임시 저장하고,
mnet_list와 mnet_dict에 나눠서 추가해줍니다.
몇가지 추가된거 말고는 위에서 진행한 방식과 같습니다.
'Coding > Python' 카테고리의 다른 글
3-3. 크롤링한 데이터를 json 파일 만들기 (3) | 2018.06.10 |
---|---|
3-2. 크롤링한 데이터를 csv 파일 만들기 (0) | 2018.06.10 |
2-4. BeautifulSoup를 이용한 Mnet 차트 크롤링 하기[함수] (0) | 2018.05.26 |
2-3. BeautifulSoup를 이용한 Mnet 차트 크롤링 하기[데이터 접근] (1) | 2018.05.22 |
2-2. BeautifulSoup를 이용한 Mnet 차트 크롤링 하기[import 모듈] (0) | 2018.05.20 |