[13일차] 웹 스크레이핑
목차
1. 웹 브라우저로 웹 사이트 접속하기
2. 웹 스크레이핑을 위한 기본 지식
3. 웹 사이트에서 데이터 가져오기
1. 웹 브라우저로 웹 사이트 접속하기
1. 하나의 웹 사이트에 접속하기
(1) 웹 브라우저를 열어서 사이트에 접속하기
import webbrowser
url = 'www.naver.com'
webbrowser.open(url)
>>> True
➡ 네이버 창이 열렸다!
(2) 웹 브라우저에 검색어 입력하여 오픈하기
- 네이버에서 파이썬 검색한 걸 열어보겠습니다☺
import webbrowser
naver_search_url = "http://search.naver.com/search.naver?query="
search_word = "파이썬"
url = naver_search_url + search_word
webbrowser.open(url)
>>> True
➡ 파이썬을 검색한 창이 열렸다!
- 구글에서 검색어 입력하여 오픈해볼까?
import webbrowser
google_url = "www.google.com/#q="
search_word = 'python'
url = google_url + search_word
webbrowser.open(url)
>>> True
➡ 🤔 True라고 뜨지만, 구글 첫 화면이 뜨고 검색어 입력된 창은 열리지 않는다.
import webbrowser
google_url = "www.google.com/search?q="
search_word = 'python'
url = google_url + search_word
webbrowser.open(url)
>>> True
➡ 구글에 python이 검색된 창이 열렸다.
👀 위 두 예시만 보더라도, 네이버는 search.naver?query= 였고 구글은 search?q= 이다. 각 포털마다 검색어를 입력받는 형식이 다르다는 걸 알 수 있다.
2. 여러 개의 웹 사이트에 접속하기
🐰 여러 개?! 그러면 for문을 돌리겠군
import webbrowser
urls = ['www.naver.com', 'www.daum.net', 'www.google.com']
for url in urls:
webbrowser.open_new(url)
➡ open_new() 를 사용하면, 새로운 창을 불러와준다🤍
(1) 여러 개의 검색어 입력하기
import webbrowser
google_url = 'www.google.com/search?q='
search_words = ['통영 네컷사진', '러브캐쳐']
for search_word in search_words:
webbrowser.open_new(google_url + search_word)
🐰 내일 통영 가는데 네컷 사진 찍고 싶어요.... 통영 가는 길에 러브캐쳐 봐야쥐 우하하
2. 웹 스크레이핑을 위한 기본 지식
1. 데이터의 요청과 응답 과정
2. HTML의 기본 구조
(1) HTML 코드를 작업 폴더 (C:/myPyCode)에 저장
%%writefile C:\myPyCode\HTML_example.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>이것은 HTML 예제</title>
</head>
<body>
<h1>출간된 책 정보</h1>
<p id = "book_title"> 내일은 실험왕 39: 영양소와 소화 </p>
<p id = "author">스토리a.</p>
<p id = "publisher">미래엔아이세움</p>
<p id = "year">2017</p>
</body>
</html>
>>> Overwriting C:\myPyCode\HTML_example.html
🐰 내가 좋아했던 만화책..ㅎㅎㅎ 이게 벌써 시즌2까지 나왔다고 하네유...... 우리 조카 사줘야겠다
- p 부분 수정
%%writefile C:\myPyCode\HTML_example2.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>이것은 HTML 예제</title>
</head>
<body>
<h1>출간된 책 정보</h1>
<p>내일은 실험왕 39: 영양소와 소화 </p>
<p>스토리a.</p>
<p>미래엔아이세움</p>
<p>2017</p>
</body>
</html>
➡ 결과는 같다. 그럼 왜 아이디를 입력한걸까?
🐰 같아보여도 다를 수 있으니까!! 늘 주의하고 다시 살펴봐야해
3. 웹 페이지의 HTML 소스 갖고 오기
(1) request를 이용하여 구글 페이지 가져오기
import requests
r = requests.get("https://google.co.kr")
r
>>> <Response [200]>
👀 <Response [200]>이면 잘 접속됐다는 것!
(2) 가져온 페이지 내용 확인하기
r.text[0:100]
>>> '<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ko"><head><meta content'
.➡ 100 미만까지 보여드려용
⬇ 🐰위에 코드랑 같이 붙이면 이렇게 코드를 짤 수 있다!
import requests
html = requests.get("https://www.google.co.kr").text
html[0:100]
>>> '<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ko"><head><meta content'
4. HTML 소스코드를 분석하고 처리하기
(1) 데이터 찾고 추출하기
👨🏻💻파싱(Parsing) = HTML의 코드 구문을 이용하고 요소별로 HTML을 분류하는 것
- BeautifulSoup 파싱을 더 수월하게 해주는 라이브러리
from bs4 import BeautifulSoup
# 테스트용 html 코드
html = """<html><body><div><span>\
<a href=https://www.naver.com>naver</a>\
<a href=https://www.google.com>google</a>\
<a href=https://www.daum.net/>daum</a>\
</span></div></body></html>"""
# BeautifuSoup를 이용해 HTML 소스를 파싱
soup = BeautifulSoup(html, 'lxml')
soup
>>> <html><body><div><span> <a href="https://www.naver.com">naver</a> <a href="https://www.google.com">google</a> <a href="https://www.daum.net/">daum</a> </span></div></body></html>
👀 차이가 크게 두드러 보이지는 않지만, 분명 차이가 존재한다!! \가 사라진 것도 차이지 암 그렇고 말고
- prettify 메서드 피싱 결과를 보기 좋게 HTML의 구조의 형태로 확인
print(soup.prettify())
>>> <html>
<body>
<div>
<span>
<a href="https://www.naver.com">
naver
</a>
<a href="https://www.google.com">
google
</a>
<a href="https://www.daum.net/">
daum
</a>
</span>
</div>
</body>
</html>
- .find() 첫번째 a 태그 찾은 후 a 태그 요소 전체를 반환
soup.find('a')
>>> <a href="https://www.naver.com">naver</a>
- .find().get_text() 태그와 속성을 제거하고 텍스트 문자열만 반환
soup.find("a").get_text()
>>> 'naver'
- .find_all() 첫 번째 a 태그를 찾은 후 모든 a 태그를 찾아서 반환
soup.find_all('a')
>>> [<a href="https://www.naver.com">naver</a>,
<a href="https://www.google.com">google</a>,
<a href="https://www.daum.net/">daum</a>]
- 혼합해서 사용하기
site_names = soup.find_all('a')
for site_name in site_names:
print(site_name.get_text())
>>> naver
google
daum
😎 테스트용 예제 2
from bs4 import BeautifulStoneSoup
# 테스트용 HTML 코드
html2 = """
<html>
<head>
<title>작품과 작가 모임</title>
</head>
<body>
<h1> 책 정보</h1>
<p id = "book_title">토지</p>
<p id = "author">박경리</p>
<p id = "book_title">태백산맥</p>
<p id = "author">조정래</p>
<p id = "book_title">감옥으로부터의 사색</p>
<p id = "author">신영복</p>
</body>
</html>"""
# BeautifuSoup를 이용해 HTML 소스를 파싱
soup2 = BeautifulSoup(html2, 'lxml')
- tilte title 추출하기
soup2.title
>>> <title>작품과 작가 모임</title>
- body body 추출하기
soup2.body
>>> <body>
<h1> 책 정보</h1>
<p id="book_title">토지</p>
<p id="author">박경리</p>
<p id="book_title">태백산맥</p>
<p id="author">조정래</p>
<p id="book_title">감옥으로부터의 사색</p>
<p id="author">신영복</p>
</body>
- h1 추출하기
soup2.body.h1
>>> <h1> 책 정보</h1>
- p태그 가져오기
soup2.find_all("p")
>>> [<p id="book_title">토지</p>,
<p id="author">박경리</p>,
<p id="book_title">태백산맥</p>,
<p id="author">조정래</p>,
<p id="book_title">감옥으로부터의 사색</p>,
<p id="author">신영복</p>]
🐰 리스트화해서 모든 p 들을 불러모았군!!
- 구분해서 가져오기 위해서는 속성도 함께 지정해 줄 수 있다.
BeautifulSoup.find_all('태크', '속성')
BeautifulSoup.find('태크', '속성')
soup2.find('p', ({'id':'book_title'}))
>>> <p id="book_title">토지</p>
soup2.find('p', ({'id':'author'}))
>>> <p id="author">박경리</p>
soup2.find_all('p',({'id':'book_title'}))
>>> [<p id="book_title">토지</p>,
<p id="book_title">태백산맥</p>,
<p id="book_title">감옥으로부터의 사색</p>]
soup2.find_all('p',({'id':'author'}))
>>> [<p id="author">박경리</p>, <p id="author">조정래</p>, <p id="author">신영복</p>]
- 텍스트만 뽑아서 묶어보기
from bs4 import BeautifulSoup
soup2 = BeautifulSoup(html2, "lxml")
book_titles = soup2.find_all('p', {'id':'book_title'})
authors = soup2.find_all('p', {'id':'author'})
for book_title, author in zip(book_titles, authors):
print(book_title.get_text() + '/' + author.get_text())
>>> 토지/박경리
>>> 태백산맥/조정래
>>> 감옥으로부터의 사색/신영복
- css (Cascading Style Sheets) 선택자를 이용하기
select('태그 및 속성') 입력하여 사용한다.
soup2.select('body h1')
>>> [<h1> 책 정보</h1>]
# p 태그를 포함한 요소를 모두 갖고 오기
soup2.select('body p')
>>> [<p id="book_title">토지</p>,
<p id="author">박경리</p>,
<p id="book_title">태백산맥</p>,
<p id="author">조정래</p>,
<p id="book_title">감옥으로부터의 사색</p>,
<p id="author">신영복</p>]
# 위 소스의 경우 p는 body에만 있으므로 생략해도 같은 값을 얻을 수 있다.
soup2.select('p')
>>> [<p id="book_title">토지</p>,
<p id="author">박경리</p>,
<p id="book_title">태백산맥</p>,
<p id="author">조정래</p>,
<p id="book_title">감옥으로부터의 사색</p>,
<p id="author">신영복</p>]
- 태그 안의 속성과 속성 값을 이용해 세밀하게 추출하기
태그.Class_속성값 태그 #id_속성값
soup2.select('p#book_title')
>>> [<p id="book_title">토지</p>,
<p id="book_title">태백산맥</p>,
<p id="book_title">감옥으로부터의 사색</p>]
soup2.select('p#author')
>>> [<p id="author">박경리</p>, <p id="author">조정래</p>, <p id="author">신영복</p>]
😎 Class 속성이 있는 HTML 예제
%%writefile C:\myPyCode\HTML_example_my_site.html
<!doctype html>
<html>
<head>
<head>
<meta charset="utf-8">
<title>사이트 모음</title>
</head>
<body>
<p id="title"><b>자주 가는 사이트 모음</b></p>
<p id="contents">이곳은 자주 가는 사이트를 모아둔 곳입니다.</p>
<a href="http://naver.com" class "portal" id="naver">네이버</a> <br>
<a href="http://google.com" class "search" id="google">구글</a> <br>
<a href="http://daum.net" class "portal" id="daum">다음</a> <br>
<a href="http://nl.go.kr" class "government" id="nl">국립중앙도서관</a><br>
</body>
</html>
>>> Writing C:\myPyCode\HTML_example_my_site.html
- 위에서 작성한 html 저장하기
f = open('C:/myPyCode/HTML_example_my_site.html', encoding='utf-8')
html3 = f.read()
f.close()
soup3 = BeautifulSoup(html3, "lxml")
- a 요소 모두 가져오기
soup3.select('a')
>>> [<a class="portal" href="http://naver.com" id="naver">네이버</a>,
<a class="search" href="http://google.com" id="google">구글</a>,
<a class="portal" href="http://daum.net" id="daum">다음</a>,
<a class="government" href="http://nl.go.kr" id="nl">국립중앙도서관</a>]
- a이면서 class가 portal인 요소만 가져오기
soup3.select('a.portal')
>>> [<a class="portal" href="http://naver.com" id="naver">네이버</a>,
<a class="portal" href="http://daum.net" id="daum">다음</a>]
(2) 웹 브라우저의 요소 검사
- a 태그를 포함하는 요소 중 id 속성이 naver인 요소 선택
soup3.select('a#naver')
>>> [<a class="portal" href="http://naver.com" id="naver">네이버</a>]
(3) 줄 바꿈으로 가독성 높이기
%%writefile C:\myPyCode\br_example_constitution.html
<!doctype html>
<html>
<head>
<title>줄 바꿈 테스트 예제</title>
</head>
<body>
<p id="title"><b>대한민국헌법</b></p>
<p id="content">제1조 <br/> 1. 대한민국은 민주공화국이다.<br/>2. 대한민국의 주권은 모든 국민에게 있고, 모든 권력은 국민으로부터 나온다.</p>
<p id="content">제2조 <br/> 1. 대한민국의 국민이 되는 요건은 법률로 정한다.<br/> 2. 국가는 법률이 정하는 바에 의하여 재외국민을 보호할 의무를 진다. </p>
</body>
</html>
>>> Overwriting C:\myPyCode\br_example_constitution.html
- 텍스트만 추출하여 출력
from bs4 import BeautifulSoup
f = open("C:/myPyCode/br_example_constitution.html",encoding='utf-8')
html_source = f.read()
f.close()
soup = BeautifulSoup(html_source,"lxml")
title = soup.find('p',{'id' : 'title'})
contents = soup.find_all('p',{'id' : 'content'})
print(title.get_text())
for content in contents:
print(content.get_text())
>>> 대한민국헌법
>>> 제1조 1. 대한민국은 민주공화국이다.
2. 대한민국의 주권은 모든 국민에게 있고, 모든 권력은 국민으로부터 나온다.
>>> 제2조 1. 대한민국의 국민이 되는 요건은 법률로 정한다.
2. 국가는 법률이 정하는 바에 의하여 재외국민을 보호할 의무를 진다.
- br 태그를 찾아 파이썬의 줄바꿈 문자 (\n)로 바꾸기
find_result = BeautifulSoup.find('태그')
find_result.replace_with('새 태그나 문자열')
html1 = '<p id="content">제1조 <br/> 1. 대한민국은 민주공화국이다. <br/>2. 대한민국의 주권은 모든 국민에게 있고, 모든 권력은 국민으로부터 나온다.</p>'
soup1 =BeautifulSoup(html1, "lxml")
print("==> 태그 p로 찾은 요소들")
content1= soup1.find('p', {"id" : "content"})
print(content1)
br_content = content1.find("br")
print("==> 결과에서 태그 br로 찾은 요소:", br_content)
br_content.replace_with("\n")
print("==> 태그 br을 개행문자로 바꾼 결과")
print(content1)
>>> ==> 태그 p로 찾은 요소들
<p id="content">제1조 <br/> 1. 대한민국은 민주공화국이다. <br/>2. 대한민국의 주권은 모든 국민에게 있고, 모든 권력은 국민으로부터 나온다.</p>
==> 결과에서 태그 br로 찾은 요소: <br/>
==> 태그 br을 개행문자로 바꾼 결과
<p id="content">제1조
1. 대한민국은 민주공화국이다. <br/>2. 대한민국의 주권은 모든 국민에게 있고, 모든 권력은 국민으로부터 나온다.</p>
- 전체 태그에 반영하기
soup2 = BeautifulSoup(html1, "lxml")
content2 = soup2.find('p', {'id' : 'content'})
br_contents = content2.find_all("br")
for br_content in br_contents:
br_content.replace_with("\n")
print(content2)
>>> <p id="content">제1조
1. 대한민국은 민주공화국이다.
2. 대한민국의 주권은 모든 국민에게 있고, 모든 권력은 국민으로부터 나온다.</p>
- 해당 기능을 함수로 만들기
def replace_newline(soup_html):
br_to_newlines = soup_html.find_all("br")
for br_to_newline in br_to_newlines:
br_to_newline.replace_with("\n")
return soup_html
- 함수와 get_text()를 이용하여 완성하기
soup2 = BeautifulSoup(html1, "lxml")
content2 = soup2.find('p',{'id':"content"})
content3 = replace_newline(content2)
print(content3.get_text())
>>> 제1조
1. 대한민국은 민주공화국이다.
2. 대한민국의 주권은 모든 국민에게 있고, 모든 권력은 국민으로부터 나온다.
- 소스코드에 파이썬 코드를 적용하여 최종 완성하기
from bs4 import BeautifulSoup
soup = BeautifulSoup(html_source, "lxml")
title = soup.find('p', {'id' : "title"})
contents = soup.find_all('p', ({'id' : "content"}))
print(title.get_text(), "\n")
for content in contents:
content1 = replace_newline(content)
print(content1.get_text(),"\n")
>>> 대한민국헌법
>>> 제1조
1. 대한민국은 민주공화국이다.
2. 대한민국의 주권은 모든 국민에게 있고, 모든 권력은 국민으로부터 나온다.
>>> 제2조
1. 대한민국의 국민이 되는 요건은 법률로 정한다.
2. 국가는 법률이 정하는 바에 의하여 재외국민을 보호할 의무를 진다.
3. 웹 사이트에서 데이터 가져오기
1. 웹 스크레이핑 시 주의 사항
- 쉬운 스크레이핑을 위해 데이터를 얻기 위한 규칙을 발견할 수 있어야 한다.
- 웹 사이트에 너무 빈번하게 접근하면 안된다. 제한 시간인나 차단이 있을 수 있다.
- 코드는 변경 될 수 있으므로 필요한 경우 지속 관리 해야 한다.
- 저작권이 있을 수 있으니 조심해야 한다.
2. 순위 데이터를 가져오기
(1) 영화 순위 : 한국 사용자들의 방문 정보를 바탕으로 웹 사이트의 순위를 알려준다.
import requests
from bs4 import BeautifulSoup
base_url = 'https://movie.naver.com/movie/sdb/rank/rmovie.naver'
date = '20230106'
url = base_url + '?sel=cnt&tg=0&date='+date # 날짜를 지정해 URL 생성
html = requests.get(url).text
soup = BeautifulSoup(html, 'lxml')
print(url)
>>> https://movie.naver.com/movie/sdb/rank/rmovie.naver?sel=cnt&tg=0&date=20230106
- 랭킹 출력
movies = soup.select('div.tit3')
movies[0:5] # 전체 중 일부만 출력
>>> [<div class="tit3">
<a href="/movie/bi/mi/basic.naver?code=74977" title="아바타: 물의 길">아바타: 물의 길</a>
</div>,
<div class="tit3">
<a href="/movie/bi/mi/basic.naver?code=184509" title="영웅">영웅</a>
</div>,
<div class="tit3">
<a href="/movie/bi/mi/basic.naver?code=223800" title="더 퍼스트 슬램덩크">더 퍼스트 슬램덩크</a>
</div>,
<div class="tit3">
<a href="/movie/bi/mi/basic.naver?code=208508" title="젠틀맨">젠틀맨</a>
</div>,
<div class="tit3">
<a href="/movie/bi/mi/basic.naver?code=201642" title="스위치">스위치</a>
</div>]
- 텍스트만 추출하기
movies[0].find('a')
>>> <a href="/movie/bi/mi/basic.naver?code=74977" title="아바타: 물의 길">아바타: 물의 길</a>
- 영화 제목과 주소만 뽑아내기
ranking_title = movies[0].find('a')['title'] # 태그 a의 요소 추출 후 title 속성 추출
ranking_href = movies[0].find('a')['href'] # 태그 a의 요소 추출 후 href 속성 추출
[ranking_title, ranking_href]
>>> ['아바타: 물의 길', '/movie/bi/mi/basic.naver?code=74977']
- 코드 통합하기
import pandas as pd
title_hrefs = [] # 빈 리스트 생성
base_url = 'https://movie.naver.com'
for movie in movies:
ranking_title = movie.find('a')['title'] # 태그 a의 요소 추출 후 title 속성 추출
ranking_href = movie.find('a')['href'] # 태그 a의 요소 추출 후 href 속성 추출
title_hrefs.append([ranking_title, base_url + ranking_href]) # 리스트의 항목 추가
# 리스트를 이용해 DataFrame 데이터 생성 (영화 순위를 index로 지정)
ranking = range(1, len(movies)+1) # 영화 순위 생성
df_movie = pd.DataFrame(title_hrefs, index = ranking, columns = ['영화 제목', '링크'])
# head()를 이용해 일부만 출력 (링크 열 너비 지정)
df_movie.head(10).style.set_properties(subset=['링크'], **{'width' : '400px'})
#df_movie # 전체 출력
(2) 주간 음악 순위 : 벅스 music에서 종합 음악 순위 정보 출력하기
import requests
from bs4 import BeautifulSoup
url = "https://music.bugs.co.kr/chart/track/week/total?chartdate=20221223" #주간 뮤직
# url = "https://music.bugs.co.kr/chart/track/realtime/total" # 실시간 뮤직 차트
# url = "https://music.bugs.co.kr/chart/track/day/total" # 일간 뮤직 차트
# url = "https://music.bugs.co.kr/chart/track/week/total" # 주간 뮤직 차트
html_music = requests.get(url).text
soup_music = BeautifulSoup(html_music, "lxml")
# p 태그의 요소 중에서 calss 속성 값이 "title" 인 것을 찾고
# 그 안에서 a 태그의 요소를 추출
titles = soup_music.select('p.title a')
titles[0:7]
>>> [<a adultcheckval="1" aria-label="새창" href="javascript:;" onclick="bugs.wiselog.area('list_tr_09_chart');bugs.music.listen('6184997',true);
" title="Ditto">Ditto</a>,
<a adultcheckval="1" aria-label="새창" href="javascript:;" onclick="bugs.wiselog.area('list_tr_09_chart');bugs.music.listen('32732271',true);
" title="NOT SORRY (Feat. pH-1) (Prod. by Slom)">NOT SORRY (Feat. pH-1) (Prod. by Slom)</a>,
<a adultcheckval="1" aria-label="새창" href="javascript:;" onclick="bugs.wiselog.area('list_tr_09_chart');bugs.music.listen('32731774',true);
" title="Candy">Candy</a>,
<a adultcheckval="1" aria-label="새창" href="javascript:;" onclick="bugs.wiselog.area('list_tr_09_chart');bugs.music.listen('6170217',true);
" title="Hype Boy">Hype Boy</a>,
<a adultcheckval="1" aria-label="새창" href="javascript:;" onclick="bugs.wiselog.area('list_tr_09_chart');bugs.music.listen('6155092',true);
" title="사건의 지평선">사건의 지평선</a>,
<a adultcheckval="1" aria-label="새창" href="javascript:;" onclick="bugs.wiselog.area('list_tr_09_chart');bugs.music.listen('6179181',true);
" title="ANTIFRAGILE">ANTIFRAGILE</a>,
<a adultcheckval="1" aria-label="새창" href="javascript:;" onclick="bugs.wiselog.area('list_tr_09_chart');bugs.music.listen('32714302',true);
" title="WHEN I MOVE">WHEN I MOVE</a>]
- 타이틀만 추출 후 보기
music_titles = [title.get_text() for title in titles]
music_titles[0:7]
>>> ['Ditto',
'NOT SORRY (Feat. pH-1) (Prod. by Slom)',
'Candy',
'Hype Boy',
'사건의 지평선',
'ANTIFRAGILE',
'WHEN I MOVE']
- 아티스트 추출하기
# p 태그의 요소 중에서 class 속서 값이 "artist" 인 것을 찾고
# 그 안에서 a 태그의 요소를 추출
artists = soup_music.select('p.artist a')
artists[0:7]
>>> [<a href="https://music.bugs.co.kr/artist/20164333?wl_ref=list_tr_10_chart" onclick="
" title="NewJeans">NewJeans</a>,
<a href="https://music.bugs.co.kr/artist/20079471?wl_ref=list_tr_10_chart" onclick="
" title="이영지">이영지</a>,
<a href="https://music.bugs.co.kr/artist/80266679?wl_ref=list_tr_10_chart" onclick="
" title="NCT DREAM">NCT DREAM</a>,
<a href="https://music.bugs.co.kr/artist/20164333?wl_ref=list_tr_10_chart" onclick="
" title="NewJeans">NewJeans</a>,
<a href="https://music.bugs.co.kr/artist/80010025?wl_ref=list_tr_10_chart" onclick="
" title="윤하(Younha/ユンナ)">윤하(Younha/ユンナ)</a>,
<a href="https://music.bugs.co.kr/artist/20158908?wl_ref=list_tr_10_chart" onclick="
" title="LE SSERAFIM (르세라핌)">LE SSERAFIM (르세라핌)</a>,
<a href="https://music.bugs.co.kr/artist/80023353?wl_ref=list_tr_10_chart" onclick="
" title="카라(Kara)">카라(Kara)</a>]
music_artists = [artist.get_text() for artist in artists]
🐰혹시 모르니까 알아둬야 하는 것.. ⬇
artists = soup_music.select('p.artist a:not(.more)')
music_artists[0:7]
>>> 'NewJeans',
'이영지',
'NCT DREAM',
'NewJeans',
'윤하(Younha/ユンナ)',
'LE SSERAFIM (르세라핌)',
'카라(Kara)']
- 종합하여 차트 히스토리에서 곡명과 아티스트 데이터를 추출하고 출력하는 코드
import requests
from bs4 import BeautifulSoup
url = "https://music.bugs.co.kr/chart/track/week/total?chartdate=20221223" #주간 뮤직
html_music = requests.get(url).text
soup_music = BeautifulSoup(html_music, "lxml")
titles = soup_music.select('p.title a')
artists = soup_music.select('p.artist')
music_titles = [title.get_text() for title in titles]
music_artists = [artist.get_text().strip() for artist in artists]
for k in range(10):
print(f"{k+1}: {music_tiltes[k]} / {music_artists[k]}")
>>> 1: Ditto / NewJeans
2: NOT SORRY (Feat. pH-1) (Prod. by Slom) / 이영지
3: Candy / NCT DREAM
4: Hype Boy / NewJeans
5: 사건의 지평선 / 윤하(Younha/ユンナ)
6: ANTIFRAGILE / LE SSERAFIM (르세라핌)
7: WHEN I MOVE / 카라(Kara)
8: Attention / NewJeans
9: All I Want for Christmas Is You / Mariah Carey(머라이어 캐리)
10: After LIKE / IVE (아이브)
- 곡명과 아티스트를 묶어서 순위별로 할당하기
music_titles_artists = {}
order = 0
for (music_title, music_artist) in zip (music_titles, music_artists):
order = order + 1
music_titles_artists[order] = [music_title, music_artist]
music_titles_artists[1]
>>> ['Ditto', 'NewJeans']
music_titles_artists[2]
>>> ['NOT SORRY (Feat. pH-1) (Prod. by Slom)', '이영지']
- 함수로 묶기
import requests
from bs4 import BeautifulSoup
# 날짜를 입력하면 벅스 차트에서 주간 음악 순위(1~100)의 곡명과 아티스트를 반환
def bugs_music_week_top100 (year, month, day):
#월과 일의 경우는 항상 두 자리로 맞춤
month = "{0:02d}".format(month)
day = "{0:02d}".format(day)
base_url = 'https://music.bugs.co.kr/chart/track/week/total?'
url = base_url + 'chartdate={0}{1}{2}'.format(year, month, day)
html_music = requests.get(url).text
soup_music = BeautifulSoup(html_music,"lxml")
titles = soup_music.select('p.title a')
artists = soup_music.select('p.artist a:not(.more)')
music_titles = [title.get_text() for title in titles]
music_artists = [artist.get_text().strip() for artist in artists]
return music_titles, music_aritsts
- 자료 저장하기
import glob
# 날짜를 지정해 bugs_music_week_top100() 함수 호출
bugs_music_titles, bugs_music_artists = bugs_music_week_top100(2023,1,9)
# 곡명과 아티스트를 저장할 파일 이름을 폴더와 함께 지정
file_name = 'C:/myPyCode/data/bugs_week_top100.txt'
f = open(file_name, 'w') # 파일 열기
# 추출된 노래 제목과 아티스트를 파일에 저장
for k in range(len(bugs_music_titles)):
f.write("{0:2d}: {1}/{2}\n".format(k+1, bugs_music_titles[k], bugs_music_artists[k]))
f.close() # 파일 닫기
glob.glob(file_name) # 생성된 파일 확인
>>> ['C:/myPyCode/data/bugs_week_top100.txt']