박봉달의 개발생활

파이썬 개인 프로젝트 1-2) Selinium을 이용해 음반 가사 웹 스크레퍼 만들기 본문

Projects/Python

파이썬 개인 프로젝트 1-2) Selinium을 이용해 음반 가사 웹 스크레퍼 만들기

박봉달 2021. 6. 11. 00:52
728x90
 

파이썬 개인 프로젝트 1) Selenium을 사용해서 음반 가사 웹 스크래퍼 만들기

오늘부터 개인 프로젝트를 시작해보려고 한다. ​ 5월까지는 꽤나 바쁘게 알고리즘 공부와 여러 자격증 공부가 있어서 시작하지 못했었는데, 6월부터는 편입공부와 함께 활용을 시작해보고 싶

things-voyager.tistory.com

저번 포스트에 이어 프로젝트를 마무리해보도록 하겠다. 이전 포스팅에서는 다 완성하지 못하고 기본적인 개념만 짚고 마무리하였는데, 이틀정도 씨름하고 나서 1차적인 프로젝트는 마무리할 수 있게 되었다. 중점이 될 소스코드의 핵심 내용은 아래와 같다.

1. Beautiful Soup

2. 셀레니움 Selenium

3. HTML 구조 파악하기

4. 동적 스크래핑

앞으로 남은 작업으로는 이렇게 되겠다.

1. 디스코드로 봇 연결 시키기

2. 코드를 이식해서 봇으로 작업을 명령하고 결과물 받아볼 수 있도록 하기

그럼 시작해 봅시다.


1. 서론

일단 머릿속으로 구상해오던 코드를 의사코드로 작성해보았다.

개인 프로젝트1 - 음반 가사 해석

1. 입력을 받음 : 명령을 내림(제목을 가지고 검색명령)

2. 파이썬으로 특정 음반 홈페이지에서 크롤링

3. 가수가 여러명이 나오면 번호로 선택

4. 그 음반의 앨범커버를 복사하여 메모장에 저장

5. 선택한 곡의 가사를 복사하여 메모장으로 붙여넣기(가사 사이에는 줄 개행 하나)

6. 메모장에서 가사를 한줄 한줄 번역기를 통해 번역시켜 메모장에 작성

이후 네이버에서 참고할 제목 + 가사 해석 블로그를 검색하여 URL 파씽 시킴

가사와 해석을 블로그에 작성하고 URL을 참고하여 포스트를 완성시킴

목표 작성시간 : 2분

* 처음에 계획했던 프로젝트는 위와 같으나, 4번의 앨범커버를 불러오는 과정에서 이미지 출력이 자꾸 안되서 아래의 순서로 작성하였다.

1. 입력을 받음 : 명령을 내림(제목을 가지고 검색명령)

2. 파이썬으로 특정 음반 홈페이지에서 크롤링 (Vibe 바이브)

3. 제목과 가수가 여러명이 나오면 번호로 선택

4. href 태그에서 링크를 스크래핑해서 해당 곡 정보로 이동 -> 가사 스크래핑 진행

5. 출력하기

그럼 프로젝트를 하나씩 뜯어보도록 하겠다.


2. 본론

일전에 BeautifulSoup와 Selinium에 대해서는 전 포스팅에 자세히(?) 작성되어있다.

이번 포스팅에서는 어떻게 곡의 정보와 id를 따왔는지를 보여주고자 한다.

바이브에서는 table 태그 안에서 tbody안에 tr 태그를 아래 곡의 타이틀과 아티스트명, 곡 고유 번호를 부여해두었다.

tbody는 처음 태그부터 접근했던 것이 아닌, 특이한 class를 가지고 있는 div 태그를 활용하여 직접 접근을 할 수 있도록 설정해두었고, 그 안의 tr 태그를 통해서 각 곡마다 접근이 가능했다. 그리고 count 변수를 활용해서 상위 5개 곡 정보까지만 긁어올 수 있게 작성했다.

  html = driver.page_source
    soup = BeautifulSoup(html, 'html.parser')
    # 곡 목록 받아오기
    tbody = soup.select_one('div.tracklist > table > tbody')
    trs = tbody.select('tr')
    datas = []  // 각 곡의 제목, 아티스트, 고유번호 저장
    count = 0  // 상위 5개 곡 정보만

    for tr in trs:
        title = tr.select_one('td.song > div.title_badge_wrap > span > a').get_text()
        artist = tr.select_one('td.artist > span > span > span > a > span').get_text()
        title_id = tr.select_one('td.song > div.title_badge_wrap > span > a')['href']
        datas.append([title, artist, title_id])
        if count < 4:
            count += 1
        else:
            break

바이브 웹페이지의 경우에는 'https://vibe.naver.com/track/48454459' 처럼 /track/00000000 으로 곡 정보에 바로 접근이 가능했다. 이걸 활용해서 title_id 의 경우에는 a 태그에 존재하는 href 정보를 긁어와서 활용할 수 있도록 작성해보았다.

 

    while 1:
        for i in range(count+1):
            print(f'{i+1}번 : {datas[i][0]} by {datas[i][1]}')
        menu = int(input("찾으시는 곡번을 선택해주세요.\n 종료하시려면 0번을 입력해주세요."))
        if menu == 0:
            break
        else:
            driver.get('https://vibe.naver.com'+datas[menu-1][2])
            html = driver.page_source
            soup = BeautifulSoup(html, 'html.parser')
            lyrics = soup.select_one('#content > div > p.lyrics').get_text()
            print(lyrics)
    driver.quit()

while 반복문을 활용하여 찾고자하는 곡의 가사가 맞는지 확인하고 아니라면 다른 번호를 입력할 수 있도록 작성해두었다.

driver.get('https://vibe.naver.com'+datas[menu-1][2]) <- 이 부분은 아까 위에서 설명했듯, href 정보에서 긁어온 곡 고유번호를 홈페이지 url과 합쳐서 홈페이지 이동을 할 수 있도록 진행했고, 이동한 페이지에서 가사를 적어둔 태그를 긁어와서 그 안의 텍스트만 읽었다.

마지막에는 webdriver를 quit() 시켜주어서 종료될 수 있도록 작성했다.

전체의 소스코드는 아래와 같다. 지금은 조금 번잡하고 함수화가 덜되긴 하였지만, 1차적인 목표는 빠르고 잘 완성시키는 것이기에 바로 공유를 한다. 시간이 여유가 된다면 조금 더 정리해서 함수화시켜보고자 한다.

# -*-coding:utf-8-*-
from bs4 import BeautifulSoup
from selenium import webdriver

def scrap():
    # webdriver 생성 및 대기
    driver = webdriver.Chrome('/Users/udtt/Downloads/chromedriver')
    driver.implicitly_wait(3)
    # 곡 입력 및 url 접근
    song = input("검색할 곡을 입력하세요\n").replace(" ", "%20")
    driver.get('https://vibe.naver.com/search/tracks?query='+song)
    # 페이지 HTML 소스 받기
    html = driver.page_source
    soup = BeautifulSoup(html, 'html.parser')
    # 곡 목록 받아오기
    tbody = soup.select_one('div.tracklist > table > tbody')
    trs = tbody.select('tr')
    datas = []
    count = 0

    for tr in trs:
        title = tr.select_one('td.song > div.title_badge_wrap > span > a').get_text()
        artist = tr.select_one('td.artist > span > span > span > a > span').get_text()
        title_id = tr.select_one('td.song > div.title_badge_wrap > span > a')['href']
        datas.append([title, artist, title_id])
        if count < 4:
            count += 1
        else:
            break

    while 1:
        for i in range(count+1):
            print(f'{i+1}번 : {datas[i][0]} by {datas[i][1]}')
        menu = int(input("찾으시는 곡번을 선택해주세요.\n 종료하시려면 0번을 입력해주세요."))
        if menu == 0:
            break
        else:
            driver.get('https://vibe.naver.com'+datas[menu-1][2])
            html = driver.page_source
            soup = BeautifulSoup(html, 'html.parser')
            lyrics = soup.select_one('#content > div > p.lyrics').get_text()
            print(lyrics)
    driver.quit()

if __name__ == "__main__":
    scrap()

3. 결론

이렇게 첫번째 파이썬 프로젝트를 마무리해보았다. 6월 6일부터 약 5일정도 진행한 프로젝트였으며, 자력으로 무언가를 만들어본 첫 경험이다. 굉장한 희열이 느껴지는 오늘이다. 이런 맛으로 개발하는건가..; 아직 완전한 마무리는 아니며, 바로 두번째 프로젝트로 디스코드 봇과 연결시켜 작동시켜보려고 한다.

무언가를 무에서 만들어내는 과정은 대부분 모방의 과정이 필요한 것 같다. 하지만 하다보면 이해가 가는 부분들이 있다. 결국 많이 해보는 것이 답인 듯 하다. 수고한 나 자신에게 상을 주고싶다.

728x90
반응형