Bactoria 황준오

유튜튜 - 유튜브 크롤링 이슈

2019-09-16
bactoria
Etc

몇일 전, 유튜튜를 들어가봤는데 문제가 생겼다.

모든 채널의 구독자 수가 증가하지 않고 있었다.

명절날 이 무슨 버그란 말인가!

 

(시간별)

 

(일별)

아이유의 구독자수는 1,559,990 이라고 하지만, 확인해보니 157만 이상이었다.

 

언제부터 안됬던건지 로그 확인해보자

select date_time +'9hours' korea_date_time, subscriber
from channel_log
where id = 'UC3SyT4_WLHzN7JmHQwKQZww';

 

(DB)

image

한국 시간으로 13일 오전 4시 넘어서부터 크롤링이 정삭적으로 되지 않았나보다.

 

(CloudWatch)

image

UTC로 2019-09-12 20시 정도부터 크롤링을 실패했다. 한국시간으로는 13일 오전 5시 조금 전이다.

166초 후에 메모리가 터졌다. 띠용..

 

왜 터졌나

현재 크롤러는 2가지가 있다.

  • 5분마다 유튜브 채널에서 구독자 수를 받아와 업데이트하는 크롤러
  • 1시간마다 DB에 있는 현재 구독자 수를 로그로 남기는 크롤러

여기서 문제가 되는 부분은 위의 크롤러이다.

만약 밑의 크롤러에 문제가 있었다면 구독자가 유지되게 나오는게 아니라, 아애 시간조차도 뜨지 않았어야 했으니까

 

아래는 AWS Lambda 에서 크롤링하는 부분의 코드이다

crwaler.py

import re
import datetime
import requests
from bs4 import BeautifulSoup as bs

KST = datetime.timezone(datetime.timedelta(hours=9))
PREFIX = 'https://www.youtube.com/channel/'
SUFFIX = '/about'
headers = {"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7"}

def crawling(channelId):

    res = requests.get(PREFIX + channelId + SUFFIX, headers=headers)
    soup = bs(res.text, 'html.parser') # 1

    subscriber = soup.find_all('span', {'class': 'subscribed'})
    subscriber = re.search('(?<=\>).*(?=\<)', str(subscriber))

    if str(type(subscriber)) == "<class 're.Match'>": 
        subscriber = subscriber.group().replace(',','') 
        if(re.search('[가-힣]', subscriber)): # 2.
            return crawling(channelId)
    else:
        subscriber = -1
        
    aboutStat = soup.find_all('span', {'class': 'about-stat'})

    views = re.search('(?<=<b>)[0-9,]+(?=</b>회)', str(aboutStat))
    if str(type(views)) == "<class 're.Match'>":
        views = views.group().replace(',', '')
    else:
        views = None

    joinDate = re.search('(?<=가입일:)[0-9. ]*', str(aboutStat))
    if str(type(joinDate)) == "<class 're.Match'>":
        joinDate = joinDate.group().split('.')

        year = int(joinDate[0])
        month = int(joinDate[1])
        day = int(joinDate[2])

        joinDate = datetime.date(year, month, day)
    else:
        joinDate = None

    title = soup.find('meta', {'property': 'og:title'})['content']
    content = soup.find('meta', {'property': 'og:description'})['content']
    image = soup.find('meta', {'property': 'og:image'})['content']
    updatedTime = datetime.datetime.now(tz=KST)

    channel = {
        'subscriber': subscriber,
        'views': views,
        'joinDate': joinDate,
        'updatedTime': updatedTime,
        'title': title,
        'content': content,
        'image': image
    }

    return channel

 

1.soup = bs(res.text, 'html.parser')

이전에는 https://www.youtube.com/channel/채널아이디/about 에 크롤링을 하면

구독자 수가 123,456 이런 식으로 나왔다.

 

2.if(re.search('[가-힣]', subscriber)):

그런데 가끔씩 한 번씩 데이터가 123,456가 아닌, 12.3만 이라고 넘어오는 경우도 있었다.

이 경우 다시 크롤링 해오는 방법으로 해결했었다.

 

image

엥…. 그럼 계속 12.3만 포맷으로 바뀐건가!!!! 구독자 정보를 더이상 자세하게 제공해주지 않는건가..

이 무슨 추석날의 선물인가..

   

유튜브의 구독자 수 변동을 알려주는 사이트에서는 이 이슈를 현재 해결했는지 궁금해서 찾아봤다.

해결 못했다. 여기도 버그투성이다. 명절이라 놀고 계신걸까

 

현재 유튜브가 제공해주는 구독자수로 그래프를 그리는 것은 과연 유의미한 것일까 싶다.


황준오 (Bactoria) 황준오 (Bactoria)

.

Comments

Content