데이터 수집에 관해 얘기를 하며
크롤링이라는 얘기를 잠깐 언급했었다.
법적인 문제야 둘째 치고라도...
기업 내부의 데이터를 직접 볼 수 없는 사람이라면
외부에서 그 정보를 수집해야만 하는데,
코딩의 코자도 모르는 사람이라도
Python과 Html을 조금만 찾아보면
간단한 데이터는 긁어올 수 있다.
웹툰 시장에서 인기 있는 작품을 보기 위해
Naver Webtoon에 나와있는 정보를 긁어와 보도록 하자.
실행하기에 앞서 준비물이 몇 가지 있는데,
자료를 긁어와서 나눠줄 Python과
Beautifulsoup이라는 라이브러리,
그리고 Selenium이라는 패키지를 설치해야 한다.
사용하는 웹 버전에 맞는 Webdriver도 필수다.
(파이썬, 라이브러리 등은 잘 모르면 일단 넘어가자)
(그리고 구글 검색은 신이다.)
준비는 완료되었다고 가정하고 ,
일단 Naver Webtoon 홈페이지에 들어가서
F12를 누르면 아래와 같은 화면을 볼 수 있다.
우리가 원하는 건 서비스 중인 전체 시리즈이므로
ORIGINAL로 들어가 보도록 하자.
여기서부터 HTML 지식이 조금 필요한데
HTML은 Tag라는 녀석을 사용한다는 것만 기억하자.
Ctrl + Shift + C를 누르면 Inspector라는 녀석이
자동으로 웹페이지의 요소를 표시해 준다.
unOrdinary라는 시리즈의 박스는
<a href = 으로 시작하는 부분을 알 수 있다.
이번에는 I Was the Final Boss라는 시리즈다.
역시나 <a href로 시작하고 있다.
어라? 뭔가 공통점이 있지 않은가?
사람은 눈치가 빨라야 한다.
박스 안에는 모두 a라는 녀석과
href뒤에 누가 봐도 웹툰 시리즈 링크가 있다.
그렇다면!!!
파이썬으로 HTML에서 a라는 녀석을 찾거나
그 위에 <li>라는 녀석을 찾으면
관련 자료를 다 가져올 수 있을 것이다.
개발을 하는 사람도 결국 사람이고
코드를 정리하려면 규칙이라는 게 있을 수밖에 없다.
HTML의 태그나 속성 같은 건 자세히 몰라도
규칙만 찾으면 자료를 찾을 수 있다는 것.
이제 파이썬으로 a라는 녀석을 긁어와 볼 차례다.
Beautifulsoup과 Selenium이라는 녀석들이
아래와 같이 입력하면 알아서 페이지로 이동해서
내용을 가져와줄 것이다.
import requests
from bs4 import BeautifulSoup
url = 'https://www.webtoons.com/en/dailySchedule'
response = requests.get(url)
if response.status_code == 200:
html = response.text
soup = BeautifulSoup(html, 'html.parser')
a_tag = soup.select('a')
print(a_tag)
문제가 발생하고 말았다.
우리가 원하는 건 시리즈와 url 등이지
페이지 내의 모든 정보는 아니었다.
그럼 시리즈 제목을 찾으려면 어떻게 해야 할까?
다시 Ctrl + Shift + C를 눌러 Inspector로
시리즈 제목을 보자.
이 녀석은 <p로 시작하고 class는 subj라고 되어있다.
아무리 봐도 subj는 시리즈의 제목 같아 보이지 않는가?
<p class="subj">unOrdinary</p>라는 부분을 우클릭하여
selector라는 녀석을 Copy 하게 되면
CSS selector를 알 수 있다.
#dailyList > div.daily_section._list_THURSDAY.on > ul > li:nth-child(1) > a > div > p.subj
역시나 p가 있고 p.subj로 확인된다.
자 그럼 파이썬에서 p.subj를 모두 가져오면
과연 어떻게 될까?
import requests
from bs4 import BeautifulSoup
url = 'https://www.webtoons.com/en/dailySchedule'
response = requests.get(url)
# print(response.status_code)
if response.status_code == 200:
html = response.text
soup = BeautifulSoup(html, 'html.parser')
title = soup.select('p.subj')
print(title)
성공이다!
제목만 추려서 모두 가져온 모습이 보인다.
여기서 조금 더 발전시켜서 작가와 장르 등
필요한 부분을 모두 가져올 수 있다.
import requests
from bs4 import BeautifulSoup
url = 'https://www.webtoons.com/en/dailySchedule'
response = requests.get(url)
# print(response.status_code)
if response.status_code == 200:
html = response.text
soup = BeautifulSoup(html, 'html.parser')
title = soup.select('p.subj')
author = soup.select('p.author')
genre = soup.select('p.genre')
like_grade = soup.select('em.grade_num')
그런데 우리는 하나의 페이지 내에서
시리즈의 세부내용이나 에피소드 개수 혹은
구독자 수를 알 수는 없다.
그럼 어떻게 해야 할까?
처음에 a 태그를 통해 가져온 내용에는
url이 포함되어있었으니,
해당 url로 이동하면 시리즈가 나올 것이고
해당 페이지에서 필요한 내용을 덧붙이면
우리가 원하는 자료를 완성할 수 있을 것이다.
그렇다면 다시 a 태그로 돌아가보자.
<a href="https://www.webtoons.com/en/super-hero/unordinary/list?title_no=679" class="daily_card_item NPI=a:list,i=679,r=1,g:en_en" data-title-unsuitable-for-children="false" data-title-unsuitable-for-children-skin="harmful_white_skin1">
<img src="https://webtoon-phinf.pstatic.net/20220201_169/16436787350192trlC_JPEG/4unOrdinary_Return_desktop_thumbnail_2.jpg?type=a138" width="138" height="138" alt="unOrdinary">
<p class="genre g_super_hero">Superhero</p>
<div class="info">
<p class="subj">unOrdinary</p>
<p class="author">uru-chan</p>
<p class="icon_area"><span class="txt_ico_up2">UP</span></p>
</div>
<p class="grade_area"><span class="ico_like3">like</span><em class="grade_num">58.1M</em></p>
</a>
a 태그 안에서 href라는 녀석 뒤에 url이 들어가 있다.
HTML에서 attribute라는 녀석이 있는데,
이 속성값이 href라는 hypertext reference의 약자라는 뜻이다.
잘 모르겠다고? 그러려니 하자.
어쨌든 href라는 녀석만 따로 뽑는다는 게 중요하다.
파이썬에서는 a 태그라는 녀석 안에,
href를 가진 값 중에서도
정상적인 링크를 가지지 않은
필요 없는 녀석들을 제외한 뒤
링크만 목록으로 쏙쏙 집어넣어줄 것이다.
lst_url_link = []
import requests
from bs4 import BeautifulSoup
url = 'https://www.webtoons.com/en/dailySchedule'
response = requests.get(url)
# print(response.status_code)
if response.status_code == 200:
html = response.text
soup = BeautifulSoup(html, 'html.parser')
title = soup.select('p.subj')
author = soup.select('p.author')
genre = soup.select('p.genre')
like_grade = soup.select('em.grade_num')
a_tag = soup.select('a')
for n in a_tag:
link = n.attrs['href']
if not 'list?title' in link:
continue
lst_url_link.append(link)
필요한 값들을 뽑는 법을 알았으니 이제는
url을 통해 시리즈 웹페이지로 이동해 보자.
Selenium은 Python에서 웹브라우저와
상호작용을 자동화 하는데 사용된다.
페이지로 이동하거나 클릭하는 등
특정 동작을 시킬 수 있는 녀석이다.
위에서 사용한 링크를 get을 이용해 가져와보자.
lst = []
lst_url_link = []
webtoon_lst = []
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
from bs4 import BeautifulSoup
driver = webdriver.Chrome()
url = 'https://www.webtoons.com/en/dailySchedule'
driver.get(url)
soup = BeautifulSoup(driver.page_source, 'html.parser')
a_tag = soup.select('a')
for n in a_tag:
link = n.attrs['href']
if not 'list?title' in link:
continue
lst_url_link.append(link)
for m in range(0, len(lst_url_link)):
#print(lst_url_link[m])
url = lst_url_link[m]
driver.get(url)
time.sleep(1)
HTML과 CSS 같은 부분을 잘 모르더라도
구글신과 함께하면 크롤링 정도는 금방 가능하다.
물론 최적화나 여러 측면에서는 부족하겠지만
몇 만 줄의 코드를 작성할 것도,
이걸로 협업을 할 것도 아니므로 신경 쓰지 말자.
작동하면 그만이다.
다음글로 이어집니다.
2023.05.22 - [Product Manager] - Product Management Research #10 (서비스 확장 / API)
'Code States' 카테고리의 다른 글
Product Management Research #11 (User Story / Agile) (0) | 2023.05.31 |
---|---|
Product Management Research #10 (서비스 확장 / API) (0) | 2023.05.22 |
Product Management Research #8 (Webtoon - 데이터수집과 분석 / 시각화) (0) | 2023.05.14 |
Product Management Research #7 (Lean Startup / Manta - Funnel, AARRR 분석) (0) | 2023.05.03 |
Product Management Research #6 (Manta - Storyboard) (0) | 2023.04.27 |