본문 바로가기
개발/python

[Python] BeautifulSoup로 YouTube에서 영상 정보를 크롤링 해보자

by 유다110 2016. 5. 15.
반응형


* 2019.04.28. 

이 글은 2016년에 쓰인 글입니다.

현재는 유튜브의 UI 레이아웃이나 태그 등이 모두 바뀌어 이 글을 따라 유튜브를 크롤링할 수 없습니다.

혹시 크롤링하는 방법을 찾아 이 글에 들어왔다면 [Python] BeautifulSoup로 웹사이트 크롤링하기 글을 참고하시기 바랍니다.




딱히 유튜브를 크롤링 하는 데에 특별하다고 할 점은 없다.

그냥 유명하고, 유명사이트다 보니 html 태그가 잘 잡혀있어서 크롤링 초보자가 이해하기 좋기 때문이다.

포스팅 전체를 읽기 귀찮다면 그냥 맨 밑의 코드만 봐도 이해는 충분히 될 것이다.

나는 Eminem 공식 페이지에서 영상 링크를 크롤링 할 건데, 에미넴 영상을 크롤링 하는 건 내가 에미넴을 좋아해서이다.

그럼 시작!



1)

일단 VS에서 어떻게, 무슨 정보를 끌어낼지 기반을 마련해 놓자.

from bs4 import BeautifulSoup

import lxml

import requests

1_크롤링 하려는 url의 response를 가져오기 위한 requests

2_html 소스를 해부하기 위한 BeautifulSoup4

3_xml 처리 모듈인 lxml

위의 모듈들은 직접 pip install이나 wheel로 받아야 한다.

특히 lxml의 경우는 파이썬 확장 패키지 사이트를 사용하는 것이 좋다.


그리고 내가 크롤링하려는 정보가 무엇인지 dict에 담아놓는다.

본인 취향에 따라 굳이 안 해도 된다. 난 이 방식이 관리하기 편해서 고른 것 뿐이다.

eminem_video_info = {

'title':'',

'video_link':'',

'img_link':'',

'play_time':'',

'hits' : '',

'updated_time':''

}



2)

그럼 이제 메소드의 틀을 만들자.

아주 간단하게 시작하기로 한다.

def get_eminem_video_link(target_url):

response = requests.get(target_url)

soup = BeautifulSoup(response.text, "lxml")

return eminem_video_info


target_url = 'https://www.youtube.com/user/EminemVEVO/videos'

get_eminem_video_link(target_url)

2, 3번째 문장이 가장 중요하다.

url로부터 response를 끌고 와서 BeautifulSoup로 html 소스를 파싱한다.

어떤 식으로 가져오는지 궁금하다면 soup를 정의한 뒤 print(soup)를 넣어보면 된다.(소스가 미친듯이 많이 나온다...)



3)

자 그럼 이제 유튜브 사이트에서 크롤링할 페이지를 고른다.

본인이 좋아하는 가수의 페이지를 하자.



4)

이 다음은 이제 html 태그를 분류해내는 일이다.

태그를 가져오려면 내가 '무슨 태그'를 가져와야 하는지 알아야 하는데, 이럴 땐 F12를 유용하게 사용할 수 있다.

F12를 누르면 아래와 같이 나타나는데 저 빨간색 부분을 누르면 내가 마우스로 가리키는 부분의 태그를 알 수 있다.


일단 내가 첫 번째로 알고 싶은 것은 영상 하나하나가 가지고 있는 고유의 태그이다.

그 태그 집합 속에 하나의 영상에 대한 제목이나 조회수, 이미지 등이 있을 테니까 말이다.

위의 F12로 이를 알아내면, 

영상 리스트 부분의 <div> 태그와 


그 <div> 태그에 속한 영상의 목록들을 찾을 수 있다.


그런데 <div> 아래에 쓸모없는 태그들이 많으니 우린 그냥 <li class="channels-content-item yt-shelf-grid-item">으로 해주자.

어차피 for loop를 돌려야 해서 이 편이 더 효율적이기도 하다.

태그를 뽑아내는 방법은 정말 쉽다.

def get_eminem_video_link(target_url):

response = requests.get(target_url)

soup = BeautifulSoup(response.text, "lxml")

lis = soup.find_all('li', {'class' : 'channels-content-item yt-shelf-grid-item'})

for li in lis :

print(li)

return eminem_video_info

만약

<li class="channels-content-item yt-shelf-grid-item">라고 돼있는 함수면,

soup.find_all('li', {'class' : 'channels-content-item yt-shelf-grid-item'}) 이런 식이다.

만약 class의 값을 모르거나, 계속 값이 변화한다면,

soup.find_all('li', {'class' : True}

이렇게 찾아도 좋다.



5)

그럼 이제 태그를 찾는 방식을 알았으니, 그 태그 안에서 내가 원하는 정보를 찾기만 하면 된다.


데이터를 뽑아내기 위해 ['title']과 같은 형식을 사용할 때도 있고, 데이터가 텍스트로 존재할 경우엔 .text 를 사용했다.

dict 하나를 출력한 결과는 다음과 같다

{'updated_time': '6개월 전', 'hits': '조회수 2,902,787회', 'title': 'Eminem - Phenomenal (Behind The Scenes)',

'video_link': 'https://www.youtube.com/watch?v=NEGjmd_RzLU', 'img_link': 'https://i.ytimg.com/vi/NEGjmd_RzL

U/hqdefault.jpg?custom=true&w=196&h=110&stc=true&jpg444=true&jpgq=90&sp=68&sigh=ZMXNqukOXArsvh0aKzMAzfzREUc',

'play_time': '8:55'}

다 뽑아낸 결과는 이렇게...




요 다음 번 포스팅에선 뽑아낸 정보를 Flask로 요리해볼까 한다.

반응형

댓글