YUDA't

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

개발/python

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

유다110 2016. 5. 15. 21:29


* 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로 요리해볼까 한다.

8 Comments
  • 프로필사진 박명석 2017.01.13 14:45 안녕하세요. 글 잘 읽어봤습니다. !
    혹시 영상정보 말고 영상 내 댓글을 크롤링하고 싶은데 더보기 같은 경우는 크롤러에서 어떻게 처리 할 수 있을까요
  • 프로필사진 유다110 2017.01.20 20:51 신고 댓글 부분은 소스를 보진 않았지만,
    직접 Firefox/Chrome 창이나 PhantomJS로 가상의 창을 띄워 더보기 버튼을 누르게 한 뒤 소스를 읽어내는 방법이 있습니다~!
    (댓글이 너무 늦었네요ㅠㅅㅠ)
  • 프로필사진 신영학 2017.01.30 19:27 저도 윗분처럼 댓글을 크롤링 하는 방법을 알고 싶은데 혹시 상세한 설명 부탁드려도 될까요?
  • 프로필사진 신영학 2017.01.30 19:44 올려주신 코드 그대로 실행해보았는데
    {'hits': u'sett 2\xa0694\xa0144 ganger',
    'img_link': 'https://i.ytimg.com/vi/5KsabeJ1UEk/hqdefault.jpg?custom=true&w=196&h=110&stc=true&jpg444=true&jpgq=90&sp=68&sigh=QFODQ2uPKZKHBHGduCYiUsHuNBA',
    'play_time': u'2:04',
    'title': 'Eminem - Berzerk Explained: Behind The Scenes 1',
    'updated_time': u'For 3 \xe5r siden',
    'video_link': 'https://www.youtube.com/watch?v=5KsabeJ1UEk'}
    이런식으로 한글이 제대로 출력이 안되서요..
    혹시 어떻게 해야 할까요?
  • 프로필사진 유다110 2017.01.31 23:16 신고 요즘 다른 일을 하고 있어서 댓글 부분은 찾아보지 못했습니다..ㅠ
    한글 출력은,
    python3는 대체로 스스로 인코딩을 잘 해줍니다만, 혹시 visual studio를 쓰고 계시다면 파일 > 고급저장옵션에서 인코딩을 utf-8로 바꿔보세요!
  • 프로필사진 코딩초보 2018.04.05 14:24 안녕하세요, 덕분에 유투브 크롤링을 할 수 있었습니다. 궁금한 점이 있어서 댓글을 남깁니다. 유튜브 같은 경우에는 스크롤을 아래로 내려 '더보기'를 활성화해야 추가적인 동영상을 볼 수 있는데, 알려주신 코드로는 이 추가적인 동영상을 더 크롤링 할 수가 없습니다. 방법이 따로 있나요?
  • 프로필사진 유다110 2018.04.16 18:14 신고 헉..댓글을 지금 봤네요...
    이건 직접 스크롤을 내려야 해서 BeautifulSoup와 별개로 selenium 모듈을 사용해야 할 것 같네요.
    BeautifulSoup보다는 좀 느리지만 selenium으로 버튼을 직접 누르거나 스크롤을 내리거나 할 수 있습니다.

    browser.execute_script("$('html').scrollTop($('html')[0].scrollHeight);")

    이렇게 javascript 코드를 실행시켜 줄 수 있죠.(위 코드는 제가 selenium으로 실제 스크롤을 내릴 때 사용한 코드입니다.)
  • 프로필사진 2018.10.25 20:22 안녕하세요 유용한 글 정말 잘 읽었습니다!

    해당 코드를 활용해서 데이터 추출까지는 성공하였는데
    어떻게 하면 저장을 할 수 있을까요?
    pandas로 저장 하려고하면 value 값들이 들어오지가 않는데 따로 이유가 있을까요? ㅜㅜ
댓글쓰기 폼