본문 바로가기

데이터분석

[PYTHON] 데이터크롤링! 인스타그램 해시태그 캐본 썰_1탄

 

 

1. 데이터 수집 목적 확인하기

 

1-1. 베이킹/디저트 관련 데이터 수집 목적

 

베이킹을 좋아하는 제가 제일 궁금했던 것은 아래 두 가지였습니다.

 

1.  인스타그램에서 가장 인기 있는 디저트 가게 Top 20 은 무엇일까?

   >> 사전에 리스트 뽑아 놓고 하나씩 도장깨기 하면 을매나 재밌게요,, 

2. 홈베이킹을 하는 사람들의 성공 요인에는 무엇이 있을까?

   >> 내가 직장인 + 홈베이커 로 활동할거였기 때문에

 

 

제일 우선 결정해야할 점은,  인기 있다는 걸 측정할 도구로 무엇을 이용할 것인가입니다.

인스타그램 크롤링을 통해 얻을 수 있는 정보는 게시글의 좋아요 수, 조회 수, 댓글 수, 해쉬태그 내용, 댓글 내용, 이미지 등등,, 많습니다. 이 중에서 저는 " 아이디, 게시일자, 게시글 좋아요 수,  본문 텍스트, 본문 해쉬태그" 를 수집하기로 했습니다. 아이디를 수집해야하는 이유는 위에 기술한 것 중에 2번 목적 때문입니다. 인기 게시물에 자주 노출되는 계정이 '홈베이킹 서적'을 내거나 '유튜브 채널'을 운영하는지, '몇 명의 팔로워를 가지고 있는지' 궁금했기 때문이죠.

 

보통 크롤링은 데이터 용량도 많고 특히 인스타그램의 경우 몇 천 개의 게시물 크롤링만 넘어가도 속도가 현저히 느려지기 때문에 (궁금해서 5000개 수집을 시도했는데, 2000개 이상부터는 현저하게 느려져서 수집을 중단하게 되었습니다), 처음 크롤링하는 목적을 떠올리며 필요한 카테고리에서 필요한 양 만큼의 데이터를 효율적으로 수집하는 건 정말 중요한 부분이라고 생각합니다.

 

 

 

1-2. 어떤 해쉬태그를 사용할 것인지 선택하기

Q. '인스타그램에서 가장 인기 있는 디저트 가게 Top 20' 을 알기위해서 어떤 해시태그를 쓸까? 

A. 인스타그램에서 디저트를 검색하고 '태그' 탭을 보면 #디저트맛집 (134만 게시물), #디저트카페(237만 게시물) 등 과 같이, 연관 해쉬태그와 그 게시물 개수가 나옵니다. 저는 이중에서 가장 많은 게시물 top 4개인 디저트(913M), 디저트카페(237M), 디저트그램(148M), 디저트맛집(134M)을 선택하였습다.

 

Q. '홈베이킹을 하는 사람들의 성공요인' 을 알기위해서 어떤 해시태그를 쓸까? 

 A-2. 홈베이킹 관련해서는 #홈베이킹(220M) 이외에는 다 10M이 채 되지 않는 해쉬태그들이어서 #베이킹(204M)으로 단어를 확장했습니다. 수집한 아이디를 바탕으로 '홈베이킹 서적' 여부와 '유튜브 채널' 운영, 네이버스토어 운영,  팔로워 수 등을 추가로 수집할 예정입니다. 

 >>베이킹 이라는 기본 단어보다 홈베이킹 이라는 단어의 게시물 수가 월등히 높은게 인상적. 

 

 

 

 

2. 데이터 크롤링 시작하기

[출처] 인스타그램 크롤링 작업을 위해 참고한 블로그는 아래와 같습니다!
- 데이터로 하는 마케팅
https://data-marketing-bk.tistory.com/9
- 솜씨좋은장씨
https://somjang.tistory.com/entry/Python-Selenium%EC%9D%84-%ED%99%9C%EC%9A%A9%ED%95%98%EC%97%AC-%EC%9D%B8%EC%8A%A4%ED%83%80%EA%B7%B8%EB%9E%A8-%ED%81%AC%EB%A1%A4%EB%A7%81-%ED%95%98%EA%B8%B0
- 씨앤텍시스템즈 기술블로그
https://cntechsystems.tistory.com/91

 

2-1. 셀레니움 설치

 

데이터 크롤링을 하기 위해서 크게 두 가지를 시행합니다.

 

(1)  Chromedriver를 설치하기 (크롬 브라우저 컨트롤을 위해서)

(2) python 에 selenium을 설치하기

 

 

우선 (1) 작업을 위해서 Chrome 최신 버전으로  업데이트를 진행합니다.

  1. Chrome 버전 확인 (크롬 화면 창의 오른쪽 상단 점3개 클릭 ➡ 설정 ➡ 왼쪽 하단 'Chrome 정보' 클릭)
  2.  크롬 최신 버전으로 업데이트 및 크롬드라이버 설치.
    주의사항: 크롬 드라이버 설치된 곳에서 .py 파일을 만들고 작업해야합니다.
    https://chromedriver.chromium.org/downloads
 

ChromeDriver - WebDriver for Chrome - Downloads

Current Releases If you are using Chrome version 93, please download ChromeDriver 93.0.4577.15 If you are using Chrome version 92, please download ChromeDriver 92.0.4515.43 If you are using Chrome version 91, please download ChromeDriver 91.0.4472.101 For

chromedriver.chromium.org

 

>>하지만 곧 이런 메세지를 만나고 마는데..

흔한 오류의 현장

Searching을 하다가, python 2와 3이 같이 설치되어 있는 경우 문제가 발생할 수 있다는 이야기를 들었습니다. Python 2를 지우고 재설치를 시도 하였으나, 해결되지 않았습니다. 

 

결국은, 가상환경을 만들어서 시도하니 설치가 잘 되었습니다 (pip upgrade, python 3.5.3 가상환경에다가 설치)

너무 보고싶었던, sucessfully installed selenium 문구

 

 

 

3. 크롤링 시작

 

3-1. 필요한 라이브러리 불러오기

 

[1] 기본으로 불러오는 라이브러리들

더보기

- urllib: 웹에 있는 소스 가져오는 패키지.

- requests: urllib안에 있는 모듈. python에서 HTTP 요청을 보냄.

- beautifulSoup: request 를 통해 가져온 긴 html에서 필요한 것만 가져오는 모듈 예쁜슾,,

- selenium: 크롤링 하기 위해서 웹브라우저를 동작 시키는 기능.

- time: 크롤링 시간 지연을 위해서.

- getpass: 인스타그램 로그인 시 암호 입력할 때.

- random: 랜덤 숫자 생성, 랜덤 관련 함수 제공.

 

다음으로, 제어될 창을 열고, 로그인 작업을 위한 코드는 아래와 같습니다. 

[2] 인스타그램 로그인

 

[3] 원하는 해쉬태그로 접속

 

 

 

 

3-2. 해시태그 기반 크롤링 시작 

 

크롤링 진행한 전체 코드는 아래와 같습니다.

seq = 0
start =time.time()

#현재 진행상황 알리기 (driver에게 css 스타일로 된 html 주소를 찾으라는 명령)
#20번째 수집이 끝나면 'n번째 수집중' 을 알림하기

while True:
    try:
        if driver.find_element_by_css_selector('a._65Bje.coreSpriteRightPaginationArrow'):
            if seq % 20 ==0:
                print(seq,'번째 수집 중', time.time() -start, sep= '\t')
                
            #ID 정보 수집

            try:
                info_id = driver.find_element_by_css_selector('body > div._2dDPU.CkGkG > div.zZYga > div > article > header > div.o-MQd > div:nth-child(1) > div > span > a').text        
                insta_dict['id'].append(info_id)
            except:
                info_id = driver.find_element_by_css_selector('body > div._2dDPU.CkGkG > div.zZYga > div > article > header > div.o-MQd > div:nth-child(1) > div > span > a').text.split()[0]
                insta_dict['id'].append(info_id)
             

            #시간 수집
            time_raw = driver.find_element_by_css_selector('body > div._2dDPU.CkGkG > div.zZYga > div > article > div.eo2As > div.EtaWk > ul > div > li > div > div > div.C4VMK > div > div > time')
            time_info = pd.to_datetime(time_raw.get_attribute('datetime'))
            insta_dict['date'].append(time_info)
            

            #like 정보 수집

            try:
                driver.find_element_by_css_selector('a.zV_Nj')
                like = driver.find_element_by_css_selector('a.zV_Nj').text
                insta_dict['like'].append(like)
            except:
                insta_dict['like'].append('0')
            

            #Text 수집

            raw_info = driver.find_element_by_css_selector('div.C4VMK').text.split()
            text =[]
            for i in range(len(raw_info)):
                if i == 0:
                    pass
                else:
                    if '#' in raw_info[i]:
                        pass
                    else:
                        text.append(raw_info[i])
            clean_text = ''.join(text)
            insta_dict['text'].append(clean_text)
            

        #해시태그 수집
        raw_tags = driver.find_elements_by_css_selector('a.xil3i')
        hash_tag =[]
        for i in range(len(raw_tags)):
            if raw_tags[i].text =='':
                pass
            else:
                hash_tag.append(raw_tags[i].text)
        insta_dict['hashtag'].append(hash_tag)
        

        seq += 1
        

        if seq == 5000:
            #게시물이 5000개 수집을 완료하면 그만하기
            break

        driver.find_element_by_css_selector('a._65Bje.coreSpriteRightPaginationArrow').click()
        time.sleep(5)
            

    except:
        driver.find_element_by_css_selector('a._65Bje.coreSpriteRightPaginationArrow').click()
        time.sleep(5)

- css(Cascading Style Sheets): www에서 시각적인 디자인과 레이아웃을 담당하는 '표현(Presentation)' 코드

 

 

3-3. 시행착오들

 

오류의 현장 1

크롤링한 결과물을 뽑아 보았더니 hashtag 들은 모두 수집된 것에 반해, date, timestamp, id, text 요소들은 2개씩만 크롤링 되었습니다. 

 

>>Trial로 40개 가져오라고 했는데, 왜 2개씩만 가져왔을까...?

 

처음에는, html class 를 잘못 찍어서 그렇다고 판단했습니다. 하지만 문제는 하나 이상 일 수 있죠. 

결국 문제는 'html class를 잘못 찍은 것과, 앞에 걸어둔 "n번째 수집중" 이라는 명령어 때문이었습니다.

 

앞에서 헛돌게 코드를 잘못 짰던 거였습니다. 결국 들여쓰기 문제여서 명령어를 적절한 들여쓰기로 쓰는 중요함을 깨달았던 시간이었습니다.

 

>> div, span, a 태그의 차이를 이해하는 것 (크롤링 할 대상에 대고>마우스 오른쪽 클릭 > 검사 > elements 확인)

 

 

 

 

글이 도움 되셨다면 좋아요, 댓글 등의 관심 부탁드려요❣
피드백을 포함한 다양한 의견도 환영합니다. 감사합니다😄

 

'데이터분석' 카테고리의 다른 글

[SQL] 어려운 문제에 깔끔한 해답,, from hackerrank  (0) 2021.10.07