인턴 하는곳에서 유튜브 정보를 크롤링하는 프로그램을 만들어달라고 하셨다.
비디오의 링크를 넣으면 그 비디오의 정보가 엑셀에 저장되는 프로그램을 만들것이다.
YOUTUBE DATA API가 있다면 기본적인 python 문법만 알고있더라도 쉽게 할 수 있다. (왜냐하면 python을 1학년때 이후로 사용해보지 않았는데도 만들었기 때문)
전체코드 : https://github.com/ankisile/youtube-crawling-with-api
1. API 키 받아오기
이 블로그를 따라하자
https://brunch.co.kr/@mystoryg/156
2. 비디오 데이터 가져오기
1. Youtube Data Api 설치
pip install google-api-python-client
2. Youtube Link 처리
youtube 링크는 다양한 형태를 띄고 있다.
따라서 각 형태에 따라 id를 가져올수 있도록 만들어야 한다.
def video_id(value):
"""
Examples:
- http://youtu.be/SA2iWivDJiE
- http://www.youtube.com/watch?v=_oPAwA_Udwc&feature=feedu
- http://www.youtube.com/embed/SA2iWivDJiE
- http://www.youtube.com/v/SA2iWivDJiE?version=3&hl=en_US
"""
query = urlparse(value)
if query.hostname == 'youtu.be':
print(query.path[1:])
return query.path[1:]
if query.hostname in ('www.youtube.com', 'youtube.com'):
if query.path == '/watch':
p = parse_qs(query.query)
print(p['v'][0])
return p['v'][0]
if query.path[:7] == '/embed/':
print(query.path.split('/')[2])
return query.path.split('/')[2]
if query.path[:3] == '/v/':
print( query.path.split('/')[2])
return query.path.split('/')[2]
# fail?
return None
3. video 정보를 받아오기 위한 설정
각 video만 받아올것이니 videos().list를 이용한다.
part에는 응답받을 내용들을 작성한다.
비디오 id와 비디오 정보들, 비디오 좋아요 수 등이 필요하므로 id, snippet, statistics 을 작성해준다.
id는 입력받을 값인데 비디오 아이디를 넣어줄 것이므로 video_id라고 해준다.
response에는 응답 받을 내용들이 저장될 것이다.
#service => connetion to youtube data api
def get_video(service, video_id):
try:
response = service.videos().list(
part="id, snippet, statistics", #응답 받을 내용들
id = video_id
).execute()
return response['items']
except HttpError as e:
errMsg = json.loads(e.content)
print('HTTP Error:')
print(errMsg['error']['message'])
4. 가져오고자 하는 값 받아오기
def video2excel(video_id):
DEVELOPER_KEY = '내 API 키'
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
# Path to the json file you downloaded:
# path_json = 'rest.json'
# with open(path_json, encoding='UTF-8') as f:
# yt = json.load(f)
# service = discovery.build_from_document(yt, developerKey=DEVELOPER_KEY)
service = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY, static_discovery=False)
video = get_video(service, video_id)
response = video[0]
if response:
row=[]
columns = ['Video Link', 'Video Title', 'Publish Date', 'Channel Name', 'Views', 'Comments','Likes','Description', 'Thumbnail' ]
rs = response['snippet']
st = response['statistics']
video_url = "https://www.youtube.com/watch?v={0}".format(response['id'])
video_title = rs['title']
video_desc = rs['description']
thumbnail = rs['thumbnails']['standard']['url'] if 'standard' in rs['thumbnails'] else rs['thumbnails']['high']['url']
channel_name =rs['channelTitle']
publish_date = rs['publishedAt'][:-1]
view_count = st['viewCount']
comment_count = st['commentCount']
like_count = st['likeCount']
row.append([video_url, video_title, publish_date, channel_name, view_count, comment_count, like_count, video_desc, thumbnail])
df = pd.DataFrame(data=row, columns=columns)
if os.path.isfile("youtube.xlsx"):
df2 = pd.read_excel("youtube.xlsx")
df= pd.concat([df2,df], axis=0)
df.to_excel("youtube.xlsx", index=False)
print("File Success")
return response['id']
최종코드는 다음과 같다.
import json
import os
import datetime
import re
import pandas as pd #엑셀 형태로 저장하기 위한 라이브러리
from googleapiclient.errors import HttpError
from googleapiclient.discovery import build
from googleapiclient import discovery
import json
from urllib.parse import urlparse, parse_qs
from pprint import pprint
#service => connetion to youtube data api
def get_video(service, video_id):
try:
response = service.videos().list(
part="id, snippet, statistics", #응답 받을 내용들
id = video_id
).execute()
return response['items']
except HttpError as e:
errMsg = json.loads(e.content)
print('HTTP Error:')
print(errMsg['error']['message'])
def video2excel(video_id):
DEVELOPER_KEY = 'AIzaSyBswrX1sQBFfVbbpLQGAeMWuT6DwxSnQiY'
YOUTUBE_API_SERVICE_NAME = "youtube"
YOUTUBE_API_VERSION = "v3"
# Path to the json file you downloaded:
# path_json = 'rest.json'
# with open(path_json, encoding='UTF-8') as f:
# yt = json.load(f)
# service = discovery.build_from_document(yt, developerKey=DEVELOPER_KEY)
service = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY, static_discovery=False)
video = get_video(service, video_id)
response = video[0]
if response:
row=[]
columns = ['Video Link', 'Video Title', 'Publish Date', 'Channel Name', 'Views', 'Comments','Likes','Description', 'Thumbnail' ]
rs = response['snippet']
st = response['statistics']
video_url = "https://www.youtube.com/watch?v={0}".format(response['id'])
video_title = rs['title']
video_desc = rs['description']
thumbnail = rs['thumbnails']['standard']['url'] if 'standard' in rs['thumbnails'] else rs['thumbnails']['high']['url']
channel_name =rs['channelTitle']
publish_date = rs['publishedAt'][:-1]
view_count = st['viewCount']
comment_count = st['commentCount']
like_count = st['likeCount']
row.append([video_url, video_title, publish_date, channel_name, view_count, comment_count, like_count, video_desc, thumbnail])
df = pd.DataFrame(data=row, columns=columns)
if os.path.isfile("youtube.xlsx"):
df2 = pd.read_excel("youtube.xlsx")
df= pd.concat([df2,df], axis=0)
df.to_excel("youtube.xlsx", index=False)
print("File Success")
return response['id']
# https://stackoverflow.com/questions/4356538/how-can-i-extract-video-id-from-youtubes-link-in-python
def video_id(value):
"""
Examples:
- http://youtu.be/SA2iWivDJiE
- http://www.youtube.com/watch?v=_oPAwA_Udwc&feature=feedu
- http://www.youtube.com/embed/SA2iWivDJiE
- http://www.youtube.com/v/SA2iWivDJiE?version=3&hl=en_US
"""
query = urlparse(value)
if query.hostname == 'youtu.be':
print(query.path[1:])
return query.path[1:]
if query.hostname in ('www.youtube.com', 'youtube.com'):
if query.path == '/watch':
p = parse_qs(query.query)
print(p['v'][0])
return p['v'][0]
if query.path[:7] == '/embed/':
print(query.path.split('/')[2])
return query.path.split('/')[2]
if query.path[:3] == '/v/':
print( query.path.split('/')[2])
return query.path.split('/')[2]
# fail?
return None
# if __name__ == "__main__":
# while True:
# url = input("url 입력 = ")
# id = video_id(url)
# video2excel(id)
3. GUI 만들기
간단한 GUI 를 만들어보았다.
링크를 입력하는 창을 넣고 링크를 입력하면 밑에 video id가 뜨도록 만들었다.
#myapp.py
import sys
from PyQt5.QtWidgets import *
import demo as ya
from PyQt5.QtCore import QTimer
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.lbl1 = QLabel('링크:', self)
self.lbl2 = QLabel('', self)
self.le = QLineEdit(self)
self.trans_btn = QPushButton('ADD', self)
self.initUI()
def initUI(self):
vbox = QVBoxLayout()
vbox.addWidget(self.lbl1)
vbox.addWidget(self.le)
vbox.addWidget(self.trans_btn)
vbox.addWidget(self.lbl2)
self.setLayout(vbox)
self.trans_btn.clicked.connect(self.translate)
# self.le.editingFinished.connect(self.translate_kor)
self.setWindowTitle('Video Information')
self.setGeometry(300, 300, 400, 200)
self.show()
def translate(self):
link = self.le.text()
print(link)
id = ya.video_id(link)
text = ya.video2excel(id)
self.lbl2.setText(text)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = MyApp()
sys.exit(app.exec_())
4. 실행파일 만들기
#pip install pyinstaller
pyinstaller --onefile --noconsole myapp.py
오류
UnknownApiNameOrVersion: name: youtube version: v3
찾아보니 static_discovery=False를 추가하라고 되어있었고 다음과 같이 변경하니 성공했다.
service = build(YOUTUBE_API_SERVICE_NAME, YOUTUBE_API_VERSION, developerKey=DEVELOPER_KEY, static_discovery=False)
참고문서