from selenium import webdriver
driver = webdriver.Safari()
url = 'https://www.naver.com'
driver.get(url)
html = driver.page_source
# 예제 2-40 실습용 HTML
html = '''
<html>
<head>
</head>
<body>
<h1> 우리동네시장</h1>
<div class = 'sale'>
<p id='fruits1' class='fruits'>
<span class = 'name'> 바나나 </span>
<span class = 'price'> 3000원 </span>
<span class = 'inventory'> 500개 </span>
<span class = 'store'> 가나다상회 </span>
<a href = 'http://bit.ly/forPlaywithData' > 홈페이지 </a>
</p>
</div>
<div class = 'prepare'>
<p id='fruits2' class='fruits'>
<span class ='name'> 파인애플 </span>
</p>
</div>
</body>
</html>
'''
from bs4 import BeautifulSoup
soup = BeautifulSoup(html, 'html.parser')
태그명이 span 인 태그와 p 인 태그를 변수에 저장
tags_span = soup.select('span')
tags_p = soup.select('p')
아이디 값이 fruits1인 태그를 모두 ids_fruits1에 저장
class 명이 price인 태그를 모두 class_price에 저장
태그명이 span이면서 class명이 price인 태그를 모두 저장
ids_fruits1 = soup.select('#fruits1')
class_price = soup.select('.price')
tags_span_class_price = soup.select('span.price')
print(ids_fruits1)
print('-'*40)
print(class_price)
print('-'*40)
print(tags_span_class_price)
print('-'*40)
print(type(ids_fruits1))
[<p class="fruits" id="fruits1">
<span class="name"> 바나나 </span>
<span class="price"> 3000원 </span>
<span class="inventory"> 500개 </span>
<span class="store"> 가나다상회 </span>
<a href="http://bit.ly/forPlaywithData"> 홈페이지 </a>
</p>]
----------------------------------------
[<span class="price"> 3000원 </span>]
----------------------------------------
[<span class="price"> 3000원 </span>]
----------------------------------------
<class 'bs4.element.ResultSet'>
태그의 속성만으로 정보를 찾기 힘들 때, 어떠한 부모 태그 아래에 있는지 등을 추가해서 검색할 수 있다. 이때 '>' 기호를 사용한다.
tags_name = soup.select('span.name')
print(tags_name)
[<span class="name"> 바나나 </span>, <span class="name"> 파인애플 </span>]
이때 바나나만 뽑아내고 싶으면 부모 태그 정보를 추가한다.
tags_banana1 = soup.select('#fruits1 > span.name')
print(tags_banana1)
[<span class="name"> 바나나 </span>]
tags_banana2 = soup.select('div.sale > #fruits1 > span.name')
tags_banana3 = soup.select('div.sale span.name')
print(tags_banana2)
print(tags_banana3)
[<span class="name"> 바나나 </span>]
[<span class="name"> 바나나 </span>]
위와 같이 '>' 기호와 띄어쓰기를 이용해서 원하는 태그를 찾을 수 있다.
tags = soup.select('span.name')
tag_1 = tags[0]
print(tags)
print(tag_1)
[<span class="name"> 바나나 </span>, <span class="name"> 파인애플 </span>]
<span class="name"> 바나나 </span>
tags = soup.select('span.name')
for tag in tags:
print(tag)
<span class="name"> 바나나 </span>
<span class="name"> 파인애플 </span>
브라우저 화면에 표시되는 정보 수집할때: .text
URL 주소 수집할때: ['href']
tags = soup.select('a')
tag = tags[0]
contect = tag.text
print(contect)
link = tag['href']
print(link)
홈페이지
http://bit.ly/forPlaywithData
driver = webdriver.Safari()
url = 'https://www.melon.com/chart/index.htm'
driver.get(url)
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
노래의 정보를 가져오는 방법은 BeautifulSoup을 이용하는 방법과 selenium을 이용하는 것 두 종류가 있다.
songs = soup.select('table > tbody > tr')
# driver.find_elements_by_css_selector('table > tbody > tr')
print(len(songs))
print(songs[0])
100
<tr data-song-no="33077590">
<td><div class="wrap t_right"><input class="input_check" name="input_check" title="VVS (Feat. JUSTHIS) (Prod. GroovyRoom) 곡 선택" type="checkbox" value="33077590"/></div></td>
<td><div class="wrap">
<a class="image_typeAll" href="javascript:melon.link.goAlbumDetail('10521601');" title="쇼미더머니 9 Episode 1">
<img alt="쇼미더머니 9 Episode 1 - 페이지 이동" height="60" onerror="WEBPOCIMG.defaultAlbumImg(this);" src="https://cdnimg.melon.co.kr/cm2/album/images/105/21/601/10521601_20201120125511_500.jpg/melon/resize/120/quality/80/optimize" width="60"/>
<span class="bg_album_frame"></span>
</a>
</div></td>
<td><div class="wrap">
<a class="btn button_icons type03 song_info" href="javascript:melon.link.goSongDetail('33077590');" title="VVS (Feat. JUSTHIS) (Prod. GroovyRoom) 곡정보"><span class="none">곡정보</span></a>
</div></td>
<td><div class="wrap">
<div class="wrap_song_info">
<div class="ellipsis rank01"><span>
<a href="javascript:melon.play.playSong('19030101',33077590);" title="VVS (Feat. JUSTHIS) (Prod. GroovyRoom) 재생">VVS (Feat. JUSTHIS) (Prod. GroovyRoom)</a>
</span></div>
<br/>
<div class="ellipsis rank02">
<a href="javascript:melon.link.goArtistDetail('2866523');" title="미란이 (Mirani) - 페이지 이동">미란이 (Mirani)</a>, <a href="javascript:melon.link.goArtistDetail('2747971');" title="먼치맨 - 페이지 이동">먼치맨</a>, <a href="javascript:melon.link.goArtistDetail('1703507');" title="Khundi Panda - 페이지 이동">Khundi Panda</a>, <a href="javascript:melon.link.goArtistDetail('2745413');" title="머쉬베놈 (MUSHVENOM) - 페이지 이동">머쉬베놈 (MUSHVENOM)</a><span class="checkEllipsis" style="display: none;"><a href="javascript:melon.link.goArtistDetail('2866523');" title="미란이 (Mirani) - 페이지 이동">미란이 (Mirani)</a>, <a href="javascript:melon.link.goArtistDetail('2747971');" title="먼치맨 - 페이지 이동">먼치맨</a>, <a href="javascript:melon.link.goArtistDetail('1703507');" title="Khundi Panda - 페이지 이동">Khundi Panda</a>, <a href="javascript:melon.link.goArtistDetail('2745413');" title="머쉬베놈 (MUSHVENOM) - 페이지 이동">머쉬베놈 (MUSHVENOM)</a></span>
</div>
<div class="wrap_atist" style="">
<button class="button_icons etc more_down" data-control="dropdown" title="아티스트 더보기" type="button"><span class="none">아티스트명 더보기</span></button>
<div class="atist_view" style="display:none;">
<ul>
<li><a class="ellipsis" href="javascript:melon.link.goArtistDetail('2866523');" title="미란이 (Mirani) 페이지 이동">미란이 (Mirani)</a></li>
<li><a class="ellipsis" href="javascript:melon.link.goArtistDetail('2747971');" title="먼치맨 페이지 이동">먼치맨</a></li>
<li><a class="ellipsis" href="javascript:melon.link.goArtistDetail('1703507');" title="Khundi Panda 페이지 이동">Khundi Panda</a></li>
<li><a class="ellipsis" href="javascript:melon.link.goArtistDetail('2745413');" title="머쉬베놈 (MUSHVENOM) 페이지 이동">머쉬베놈 (MUSHVENOM)</a></li>
</ul>
</div>
</div>
</div>
</div></td>
<td><div class="wrap">
<div class="wrap_song_info">
<div class="ellipsis rank03">
<a href="javascript:melon.link.goAlbumDetail('10521601');" title="쇼미더머니 9 Episode 1 - 페이지 이동">쇼미더머니 9 Episode 1</a>
</div>
</div>
</div></td>
<td><div class="wrap">
<button class="button_etc like" data-song-menuid="19030101" data-song-no="33077590" title="VVS (Feat. JUSTHIS) (Prod. GroovyRoom) 좋아요" type="button"><span class="odd_span">좋아요</span>
<span class="cnt">
<span class="none">총건수</span>
151,647</span></button>
</div></td>
<td><div class="wrap t_center">
<button class="button_icons play" onclick="melon.play.playSong('19030101',33077590);" title="듣기" type="button"><span class="none">듣기</span></button>
</div></td>
<td><div class="wrap t_center">
<button class="button_icons scrap" onclick="melon.play.addPlayList('33077590');" title="담기" type="button"><span class="none">담기</span></button>
</div></td>
<td><div class="wrap t_center">
<button class="button_icons download" onclick="melon.buy.goBuyProduct('frm', '33077590', '3C0001', '','0', '19030101');" title="다운로드" type="button"><span class="none">다운로드</span></button>
</div></td>
<td><div class="wrap t_center">
<button class="button_icons video disabled" disabled="disabled" onclick="melon.link.goMvDetail('19030101', '33077590','song');" title="뮤직비디오" type="button"><span class="none">뮤직비디오</span></button>
</div></td>
</tr>
len()
의 결과가 100 이므로 1위부터 100위의 곡 수와 일치한다. 이번엔 먼저 1위 곡의 노래 제목과 가수를 찾아서 반복문으로 100곡의 제목과 가수를 찾아보자.
song = songs[0]
title = song.select('a')
len(title)
16
태그명이 a인 태그가 16개인데 이 중 곡 제목이 포함된 태그만 가져오려면 조건을 추가해야한다.
title = song.select('span > a')
len(title)
5
아직도 5개가 나오므로 조건을 더 추가하자.
title = song.select('div.ellipsis.rank01 > span > a')
len(title)
1
title
[<a href="javascript:melon.play.playSong('19030101',33077590);" title="VVS (Feat. JUSTHIS) (Prod. GroovyRoom) 재생">VVS (Feat. JUSTHIS) (Prod. GroovyRoom)</a>]
이제 여기서 title 부분만 추출하자.
title = song.select('div.ellipsis.rank01 > span > a')[0].text
title
'VVS (Feat. JUSTHIS) (Prod. GroovyRoom)'
이번엔 가수를 찾아보자. 가수는 div와 a 태그에 포함되어 있다.
singer = song.select('div.ellipsis.rank02 > a')
len(singer)
4
singer = song.select('div.ellipsis.rank02 > a')[0].text
singer
'미란이 (Mirani)'
책이랑 다르게 쇼미의 힘인지 가수가 여러명인 노래가 1위이다.. 책의 코드들을 수정해야할 것으로 보인다.
# 가수가 여러명인 경우 가수 이름을 저장하는 방법
len_singer = len(song.select('div.ellipsis.rank02 > a'))
singer = ""
for i in range(len_singer):
singer += song.select('div.ellipsis.rank02 > span > a')[i].text + ", "
singer
'미란이 (Mirani), 먼치맨, Khundi Panda, 머쉬베놈 (MUSHVENOM), '
책의 1위부터 100위까지 가수와 노래 제목을 구하는 for문
for song in songs:
title = song.select('div.ellipsis.rank01 > span > a')[0].text
singer = song.select('div.ellipsis.rank02 > span > a')[0].text
print(title, singer, sep= '|')
for song in songs:
title = song.select('div.ellipsis.rank01 > span > a')[0].text
singer = ""
len_singer = len(song.select('div.ellipsis.rank02 > a'))
for i in range(len_singer):
singer += song.select('div.ellipsis.rank02 > span > a')[i].text + ", "
print(title, singer, sep = ' | ')
VVS (Feat. JUSTHIS) (Prod. GroovyRoom) | 미란이 (Mirani), 먼치맨, Khundi Panda, 머쉬베놈 (MUSHVENOM),
밤하늘의 별을(2020) | 경서,
Dynamite | 방탄소년단,
잠이 오질 않네요 | 장범준,
내일이 오면 (Feat. 기리보이, BIG Naughty (서동현)) | 릴보이 (lIlBOI),
힘든 건 사랑이 아니다 | 임창정,
취기를 빌려 (취향저격 그녀 X 산들) | 산들,
Lovesick Girls | BLACKPINK,
Life Goes On | 방탄소년단,
오래된 노래 | 스탠딩 에그,
CREDIT (Feat. 염따, 기리보이, Zion.T) | 릴보이 (lIlBOI),
Savage Love (Laxed - Siren Beat) (BTS Remix) | Jawsh 685, Jason Derulo, 방탄소년단,
내 마음이 움찔했던 순간 (취향저격 그녀 X 규현) | 규현 (KYUHYUN),
나랑 같이 걸을래 (바른연애 길잡이 X 적재) | 적재,
어떻게 이별까지 사랑하겠어, 널 사랑하는 거지 | AKMU (악동뮤지션),
Achoo (Feat. pH-1, HAON) (Prod. GroovyRoom) | 미란이 (Mirani),
에잇(Prod.&Feat. SUGA of BTS) | 아이유,
When We Disco (Duet with 선미) | 박진영,
ON AIR (Feat. 로꼬, 박재범 & GRAY) | 릴보이 (lIlBOI),
Freak (Prod. Slom) | 릴보이 (lIlBOI), 원슈타인, Chillin Homie, 스카이민혁 (Skyminhyuk),
혼술하고 싶은 밤 | 벤,
흔들리는 꽃들 속에서 네 샴푸향이 느껴진거야 | 장범준,
늦은 밤 너의 집 앞 골목길에서 | 노을,
어떻게 지내 (Prod. By VAN.C) | 오반 (OVAN),
How You Like That | BLACKPINK,
모든 날, 모든 순간 (Every day, Every Moment) | 폴킴,
딩가딩가 (Dingga) | 마마무 (Mamamoo),
뿌리 (Feat. JUSTHIS) (Prod. GroovyRoom) | Khundi Panda,
아로하 | 조정석,
METEOR | 창모 (CHANGMO),
Blueming | 아이유,
Dolphin | 오마이걸 (OH MY GIRL),
서면역에서 | 순순희,
DON'T TOUCH ME | 환불원정대,
사실 나는 (Feat.전건호) | 경서예지,
악역 (Feat. 이하이 & 사이먼 도미닉) (Prod. 코드 쿤스트) | 스윙스,
마음을 드려요 | 아이유,
작은 것들을 위한 시 (Boy With Luv) (Feat. Halsey) | 방탄소년단,
I CAN’T STOP ME | TWICE (트와이스),
거짓말이라도 해서 널 보고싶어 | 백지영,
오늘도 빛나는 너에게 (To You My Light) (Feat.이라온) | 마크툽 (MAKTUB),
마리아 (Maria) | 화사 (Hwa Sa),
뻔한남자 | 이승기,
Memories | Maroon 5,
시작 | 가호 (Gaho),
그날에 나는 맘이 편했을까 | 이예준,
Snowman | Sia,
사랑은 지날수록 더욱 선명하게 남아 | 전상근,
우리 왜 헤어져야 해 | 신예영,
홀로 | 이하이,
봄날 | 방탄소년단,
고독하구만 (Feat. 수퍼비) (Prod. GroovyRoom) | 머쉬베놈 (MUSHVENOM),
눈누난나 (NUNU NANA) | 제시 (Jessi),
All I Want For Christmas Is You | Mariah Carey,
가을밤에 든 생각 | 잔나비,
살짝 설렜어 (Nonstop) | 오마이걸 (OH MY GIRL),
Santa Tell Me | Ariana Grande,
Dance Monkey | Tones And I,
한잔이면 지워질까 | 황인욱,
Downtown Baby | 블루 (BLOO),
2002 | Anne-Marie,
What Do I Call You | 태연 (TAEYEON),
사랑 못해, 남들 쉽게 다 하는 거 | 먼데이 키즈 (Monday Kiz),
안녕 | 폴킴,
너를 만나 | 폴킴,
소확행 | 임창정,
미리 메리 크리스마스 (Feat. 천둥 Of MBLAQ) | 아이유,
Panorama | IZ*ONE (아이즈원),
나로 바꾸자 (duet with JYP) | 비,
여백의 미 (Feat. Jessi, JUSTHIS) (Prod. GroovyRoom) | 머쉬베놈 (MUSHVENOM),
잘할게 | 이승기,
처음처럼 | 엠씨더맥스 (M.C the MAX),
행복해 | 송하예,
사랑하게 될 줄 알았어 | 전미도,
Love poem | 아이유,
이제 나만 믿어요 | 임영웅,
너의 번호를 누르고 (Prod. 영화처럼) | #안녕,
너도 아는 | 폴킴,
Don't Start Now | Dua Lipa,
우린 어쩌다 헤어진 걸까 | 허각,
별을 담은 시 (Ode To The Stars) | 마크툽 (MAKTUB), 이라온,
아무노래 | 지코 (ZICO),
다시 여기 바닷가 | 싹쓰리 (유두래곤, 린다G, 비룡),
12:45 (Stripped) | Etham,
Bad Boy | 청하, Christopher,
적외선 카메라 | 원슈타인,
놓아줘 (with 태연) | Crush,
Paris In The Rain | Lauv,
Maniac | Conan Gray,
가다 (Feat. 사이먼 도미닉, The Quiett) (Prod. SLO) | 머쉬베놈 (MUSHVENOM),
원해 (Feat. 팔로알토) (Prod. 코드 쿤스트) | 스윙스, 맥대디 (Mckdaddy), Khakii (카키), 래원 (Layone),
ON | 방탄소년단,
Black Mamba | aespa,
For You (Feat. Crush) | 이하이,
12월의 어느 겨울… | 윤도 (YoonDo),
Blue & Grey | 방탄소년단,
요즘 | 양다일,
내 방을 여행하는 법 | 방탄소년단,
크리스마스니까 | 성시경, 박효신, 이석훈, 서인국, VIXX (빅스),
모든 밤 너에게 (연애혁명 X 민현 (뉴이스트)) | 민현 (뉴이스트),
직장인을 위한 데이터 분석 실무 파이썬 / 위키북스