반응형
API를 활용한 유튜브 크롤링¶
시험삼아 즐겨보는 유튜버 '런업'님의 채널의 동영상에 대한 데이터를 불러모아보았다.
In [1]:
# 필요한 패키지 설치
# !pip install --upgrade google-api-python-client
# !pip install oauth2client
In [2]:
from googleapiclient.discovery import build
from googleapiclient.errors import HttpError
from oauth2client.tools import argparser
# https://console.cloud.google.com/apis/credentials 여기서 API발급받아 사용
DEVELOPER_KEY='내 키값 입력' # 내 API 키값 입력
YOUTUBE_API_SERVICE_NAME='youtube'
YOUTUBE_API_VERSION='v3'
youtube=build(YOUTUBE_API_SERVICE_NAME,YOUTUBE_API_VERSION,developerKey=DEVELOPER_KEY)
In [3]:
# q에 원하는 채널 이름 넣는다
search_response=youtube.search().list(
q="런업",
order='relevance',
part='snippet',
maxResults=50,
).execute()
In [4]:
search_response['items'][0]
Out[4]:
{'kind': 'youtube#searchResult', 'etag': 'VdmHRxh5s5HuNDokW4gQP6pLBM8', 'id': {'kind': 'youtube#channel', 'channelId': 'UC6VzIz8tJLnetS79VbsHPGg'}, 'snippet': {'publishedAt': '2017-07-19T10:40:15Z', 'channelId': 'UC6VzIz8tJLnetS79VbsHPGg', 'title': '런업', 'description': 'Life style #Fashion #IT 서울 사는 40대 남자의 라이프 스타일 어른의 호기심으로 본 사람과 사물, 이들이 엮여 만드는 서울의 일상을 담습니다. 어른들의 지식 ...', 'thumbnails': {'default': {'url': 'https://yt3.ggpht.com/ytc/AKedOLSFhIYeCz1cnmsRndX0TpwqeDYVikZpVBuXfd4TEw=s88-c-k-c0xffffffff-no-rj-mo'}, 'medium': {'url': 'https://yt3.ggpht.com/ytc/AKedOLSFhIYeCz1cnmsRndX0TpwqeDYVikZpVBuXfd4TEw=s240-c-k-c0xffffffff-no-rj-mo'}, 'high': {'url': 'https://yt3.ggpht.com/ytc/AKedOLSFhIYeCz1cnmsRndX0TpwqeDYVikZpVBuXfd4TEw=s800-c-k-c0xffffffff-no-rj-mo'}}, 'channelTitle': '런업', 'liveBroadcastContent': 'none', 'publishTime': '2017-07-19T10:40:15Z'}}
In [5]:
channel_id=search_response['items'][0]['id']['channelId']
In [6]:
# 채널관리자가 올려놓은 플레이리스트로 받아온다
playlists=youtube.playlists().list(
channelId=channel_id,
part='snippet',
maxResults=20).execute()
In [7]:
playlists['items'][0]
Out[7]:
{'kind': 'youtube#playlist', 'etag': 'np04gx53nocCEofEMmtbM-VADqw', 'id': 'PL3PddQE0Wo9cWMCCDy641kcA28zss5ul8', 'snippet': {'publishedAt': '2021-07-08T10:05:39Z', 'channelId': 'UC6VzIz8tJLnetS79VbsHPGg', 'title': '런업플레이리스트2021', 'description': '', 'thumbnails': {'default': {'url': 'https://i.ytimg.com/vi/92-sXUtLfSs/default.jpg', 'width': 120, 'height': 90}, 'medium': {'url': 'https://i.ytimg.com/vi/92-sXUtLfSs/mqdefault.jpg', 'width': 320, 'height': 180}, 'high': {'url': 'https://i.ytimg.com/vi/92-sXUtLfSs/hqdefault.jpg', 'width': 480, 'height': 360}, 'standard': {'url': 'https://i.ytimg.com/vi/92-sXUtLfSs/sddefault.jpg', 'width': 640, 'height': 480}, 'maxres': {'url': 'https://i.ytimg.com/vi/92-sXUtLfSs/maxresdefault.jpg', 'width': 1280, 'height': 720}}, 'channelTitle': '런업', 'localized': {'title': '런업플레이리스트2021', 'description': ''}}}
In [8]:
import pandas as pd
ids=[]
titles=[]
for i in playlists['items']:
ids.append(i['id'])
titles.append(i['snippet']['title'])
df=pd.DataFrame([ids,titles]).T
df.columns=['PlayLists','Titles']
In [9]:
df.head(10) #playlist ID 값
Out[9]:
PlayLists | Titles | |
---|---|---|
0 | PL3PddQE0Wo9cWMCCDy641kcA28zss5ul8 | 런업플레이리스트2021 |
1 | PL3PddQE0Wo9cexNVNmGTceU8RM8cwLo58 | 스토리타임 |
2 | PL3PddQE0Wo9cqTy5OCphvncYal0AdS7Dn | youtube classic |
3 | PL3PddQE0Wo9f8S_r5mSNaHz_sjKbgkywq | 런업 플레이리스트 2020 |
4 | PL3PddQE0Wo9fkXwiE0oFFCQtKYLH7ZbSB | 패션 |
5 | PL3PddQE0Wo9eULl5qjPjSgT9pqBBHerIN | RUNNiNG2 |
6 | PL3PddQE0Wo9fSx-S_1PCnj8pZbZa61QME | RUNNiNG |
7 | PL3PddQE0Wo9dxskyruSHmaWBmMipiMeEi | DISCO BITCH |
8 | PL3PddQE0Wo9e9lWjJ4i_FAtNStj8q3KD_ | 런업이 추천하는 가을플레이리스트 |
9 | PL3PddQE0Wo9fnLxglYpsi1mwGf-Eqo0qv | 업을 배우다 - 다양한 직업군 인터뷰 learn業 |
In [10]:
#영상 list
dtcu=df['PlayLists'][10]
playlist_videos=youtube.playlistItems().list(
playlistId=dtcu,
part='snippet',
maxResults=50)
In [11]:
playlistitems_list_response=playlist_videos.execute()
video_names=[]
video_ids=[]
date=[]
for v in playlistitems_list_response['items']:
video_names.append(v['snippet']['title'])
video_ids.append(v['snippet']['resourceId']['videoId'])
date.append(v['snippet']['publishedAt'])
vdf=pd.DataFrame([date,video_names,video_ids]).T
vdf.columns=['Date','Title','IDS']
In [12]:
vdf.tail(10)
Out[12]:
Date | Title | IDS | |
---|---|---|---|
32 | 2019-08-10T13:56:00Z | [재테크] p2p업체와 상품 선별! [업계 초고수의 비밀을 알려드립니다] 부동산 p... | 4ebyL1lGwNE |
33 | 2019-08-10T13:46:22Z | Private video | 9KuKrTvzy0E |
34 | 2019-08-10T13:43:58Z | Private video | Tq6Vs6C3_FU |
35 | 2019-08-10T13:44:49Z | 리뷰하고 싶지 않았다. 릴 하이브리드 | g7meYxE1-EU |
36 | 2019-08-10T13:46:39Z | 와썹맨 슈링크 맞아 보았다 효과 대체 무엇??? | ojFhnsa-22M |
37 | 2020-02-13T15:12:47Z | 실제 투표해봄-여자들에게 어필할 수 있는 남자향수는? | VaWAqaej2pI |
38 | 2020-05-11T04:22:29Z | 나이먹고 결혼하면 이렇습니다 | G7Iz4B1XrVA |
39 | 2020-05-11T04:24:22Z | 결혼하는법 pt.2 | M5PAjQSS6Gg |
40 | 2020-05-11T05:08:11Z | 내가 결혼은 못(x)안(o)하고 있는 이유- 40대의 결혼관 | _mLrT_AuSRA |
41 | 2021-08-04T15:17:00Z | 나는 과연 사업가 체질인가? | sTnO9DwtHiw |
In [13]:
#영상 관련 수치
import re
category_id=[]
views=[]
likes=[]
dislikes=[]
# comments=[]
mins=[]
seconds=[]
title=[]
date=[]
for u in range(len(vdf)):
request=youtube.videos().list(
part='snippet,contentDetails,statistics',
id=vdf['IDS'][u])
response=request.execute()
if response['items']==[]:
ids.append('-')
category_id.append('-')
views.append('-')
likes.append('-')
dislikes.append('-')
# comments.append('-')
date.append('-')
else :
title.append(response['items'][0]['snippet']['title'])
category_id.append(response['items'][0]['snippet']['categoryId'])
views.append(response['items'][0]['statistics']['viewCount'])
likes.append(response['items'][0]['statistics']['likeCount'])
dislikes.append(response['items'][0]['statistics']['dislikeCount'])
# comments.append(response['items'][0]['statistics']['commentCount']) # commentCount가 있는게 있고 없는게 있다.
date.append(response['items'][0]['snippet']['publishedAt'])
In [17]:
# dtcu_df=pd.DataFrame([title,category_id,views,likes,dislikes,comments,date]).T
dtcu_df=pd.DataFrame([title,category_id,views,likes,dislikes,date]).T # comment제외
# dtcu_df.columns=['title','category_id','views','likes','dislikes', 'comments','date']
dtcu_df.columns=['title','category_id','views','likes','dislikes','date'] # comments제외
# 이외에도 description, tag도 불러올 수 있다.
In [18]:
dtcu_df.head(10)
Out[18]:
title | category_id | views | likes | dislikes | date | |
---|---|---|---|---|---|---|
0 | 돈만 많이 벌면 된다는 사람들에게 | 22 | 353990 | 10732 | 274 | 2019-03-29T14:20:57Z |
1 | 영앤리치- 그들은 어떻게 괴물이 되었나 | 22 | 431753 | 9470 | 224 | 2019-03-13T14:14:23Z |
2 | 좋아하는 일을 찾는 방법을 알려줍니다 pt. 1 | 22 | 264873 | 10259 | 115 | 2019-05-26T13:54:50Z |
3 | 무스탕 사러 동대문 가기 무섭다고요? - 광희시장 공략집 | 22 | 104138 | 1134 | 49 | 2018-12-14T14:54:00Z |
4 | (대학에서 꼭 배워야 할)인생에서 가장 중요한 기술 | 22 | 161780 | 4534 | 72 | 2019-04-21T11:40:13Z |
5 | 강릉에서 요즘 괜찮다는 세인트존스 호텔에 가 보았습니다 | 22 | 72697 | 763 | 93 | 2018-09-07T16:44:07Z |
6 | 하루에 몇시간 앉아있나요? 시디즈t80x 마블 완벽리뷰! 좋은 의자는 인생을 바꿉니다. | 22 | 55150 | 442 | 70 | 2018-04-29T15:25:05Z |
7 | 탈모를 이겨내는 헤어스타일링 ft. 청담 void H 원장 오영환 | 22 | 48408 | 619 | 25 | 2017-12-27T13:26:51Z |
8 | 요즘 유행하는 청바지 고르는 법 - 아크네스튜디오 | 22 | 109269 | 1321 | 45 | 2019-02-13T17:46:31Z |
9 | [스타필드고양] 거의 완벽리뷰할 고양!!!! (Vlog는 덤) | 22 | 49600 | 413 | 59 | 2017-08-19T08:24:16Z |
In [ ]:
반응형
'Skills > Python' 카테고리의 다른 글
[Python] selenium 패키지를 활용한 크롤링 (1) | 2021.11.08 |
---|---|
[Python] API를 통해 크롤링하기 (0) | 2021.11.08 |
[Python] 크롤링이 잘되었는지 확인하는 법 & 차단 방지하는 법 (0) | 2021.11.08 |
[Python] selenium 패키지 사용을 위한 chromedriver 설치 및 오류해결(Mac OS) (0) | 2021.11.08 |
[Python] 웹 페이지 크롤링 기초 (0) | 2021.11.08 |