JSP's Deep learning

[Crawling Practice] 3. 인스타그램 크롤링 본문

Data Processing/Crawling Practice

[Crawling Practice] 3. 인스타그램 크롤링

_JSP_ 2022. 5. 26. 13:08

이번에 할 크롤링은 인스타그램의 게시글입니다~

 

게시글의 사진, 날짜, 좋아요, 해시태그를 크롤링해서 저장하는 것이 목표!

 

이번에는 코드를 좀더 가독성있게 보기위해 함수화를 시켰습니다!

 


1. 패키지 로드

import pandas as pd
import numpy as np

from selenium import webdriver 
from selenium.webdriver import ActionChains as AC
import chromedriver_autoinstaller

from tqdm import tqdm
from tqdm import tqdm_notebook

import re # 데이터 전처리 : 정규표현식

from time import sleep
import time

# 이미지 파일을 저장하기 위함
import os
import urllib.request

# 워닝 무시
import warnings
warnings.filterwarnings('ignore')

 

2. 검색할 키워드와 수집할 게시글 입력

keyword = input("크롤링할 키워드 입력:")
len_insta = int(input("수집할 게시글 개수 입력:"))

저는 요즘 득점왕으로 핫한 손흥민 선수의 개인 브랜드 NOS7에 대해서 20개 정도의 게시글을 크롤링 해봅니다!

 

3. 크롤링 메서드

def connect_insta(keyword : str):
    '''인스타 접속'''
    # url에 검색 'keyword' 입력
    url = "https://www.instagram.com/explore/tags/{}/".format(keyword)
    chrome_path = chromedriver_autoinstaller.install()
    driver = webdriver.Chrome(chrome_path)
    driver.get(url)
    return driver
    
def login_insta(ID : str, PASSWORD : str, driver):
    '''인스타 로그인'''
    # 로그인 창 접속
    element = driver.find_element_by_css_selector('._7UhW9.xLCgt.qyrsm.uL8Hv.T0kll ')
    element.click()
    sleep(1)
    element = driver.find_element_by_xpath('//*[@id="loginForm"]/div[1]/div[1]/div/label/input')
    
    # ID 입력
    element.click()
    element.clear()
    element.send_keys(ID)
    sleep(1)
    
    # PASSWORD 입력
    element = driver.find_element_by_xpath('//*[@id="loginForm"]/div[1]/div[2]/div/label/input')
    element.click()
    element.clear()
    element.send_keys(PASSWORD)
    sleep(1)
    
    # 로그인
    element.submit()
    sleep(7) # 로딩시간이 길기 때문에 넉넉하게 7초 대기
    
    # 부가적으로 뜨는 창 닫기
    try : 
        element = driver.find_element_by_xpath('//*[@id="react-root"]/section/main/div/div/div/div/button')
        element.click()
        sleep(5)

        element = driver.find_element_by_xpath('/html/body/div[5]/div/div/div/div[3]/button[2]')
        element.click()
        sleep(1)
    except:
        pass
        

def click_first_image(driver):
    '''첫번째 사진 클릭'''
    CSS_tran=".eLAPa"
    elements = driver.find_elements_by_css_selector(CSS_tran)   # 사진 클릭
    elements[0].click()
    time.sleep(2)
    
def crawling_img(driver):
    '''사진(pic) 크롤링'''
    overlays1 = ".KL4Bh .FFVAD"                   # 사진창 속 사진   
    img = driver.find_element_by_css_selector(overlays1)    # 사진 선택
    pic = img.get_attribute('src')                          # 사진 url 크롤링 완료
    return pic

def crawling_date(driver):
    '''날짜(date) 크롤링'''
    overlays2 = "._1o9PC"                # 날짜 지정
    datum2 = driver.find_element_by_css_selector(overlays2)     # 날짜 선택
    date = datum2.get_attribute('title')
    return date

def crawling_like(driver):
    '''좋아요(like) 크롤링'''
    overlays3 = "._7UhW9.xLCgt.qyrsm.KV-D4.fDxYl.T0kll"                                        # 리뷰창 속 날짜
    datum3 = driver.find_element_by_css_selector(overlays3)     # 리뷰 선택
    like = datum3.text                                          # 좋아요 크롤링 완료
    return like

def crawling_tag(driver):
    '''해시태그(tag) 크롤링'''
    overlays4 = ".xil3i"                                         
    datum3 = driver.find_elements_by_css_selector(overlays4)    # 태그 선택
    tag_list = []
    for i in range(len(datum3)):
        tag_list.append(datum3[i].text)
    return tag_list
    
def click_next_page(driver):
    '''다음 장 클릭'''
    CSS_tran2="body > div.RnEpo._Yhr4 > div.Z2Inc._7c9RR > div > div.l8mY4.feth3 > button > div > span > svg"             # 다음 버튼 정의
    tran_button2 = driver.find_element_by_css_selector(CSS_tran2)  # 다음 버튼 find
    AC(driver).move_to_element(tran_button2).click().perform()     # 다음 버튼 클릭
    time.sleep(3)

 

4. 파일 저장 메서드

def save_to_csv(dic, keyword):
    result_df = pd.DataFrame.from_dict(dic, 'index')
    result_df.to_csv("insta({}).csv".format(keyword), encoding='utf-8-sig')
    return result_df
    
def save_img(result_df):
    # 이미지들 image_insta 폴더에 다운받기
    import os
    import urllib.request
    
    num_pic = len(result_df['picture'])
    
    # 만약 image_insta 폴더가 없으면 만들어라
    if not os.path.exists("image_insta"):
        os.makedirs("image_insta")

    for i in range(0, num_pic):
        try:
            index = result_df['picture'][i]
            date = result_df['date'][i]
            urllib.request.urlretrieve(index, "image_insta/{0}_{1}.jpg".format(date, i))        
        except:
            pass

 

5. 동작 코드

dict = {}  # 전체 게시글을 담을 그릇
driver = connect_insta(keyword) # 인스타 접속
login_insta("아이디", "비밀번호", driver) # 로그인
click_first_image(driver) # 첫번째 이미지 클릭

# 크롤링 시작
for j in tqdm_notebook(range(0, len_insta)):    

    target_info = {}                                            # 사진별 데이터를 담을 딕셔너리 생성

    try:    # 크롤링을 시도해라.
        # 사진(pic) 크롤링
        target_info['picture'] = crawling_img(driver)

        # 날짜(date) 크롤링
        target_info['date'] = crawling_date(driver)

        # 좋아요(like) 크롤링
        target_info['like'] = crawling_like(driver)

        # 해시태그(tag) 크롤링
        target_info['tag'] = crawling_tag(driver)

        dict[j] = target_info            # 토탈 딕셔너리로 만들기
        print(j, tag_list)

        # 다음장 클릭
        click_next_page(driver)

    except:  # 에러가 나면 다음장을 클릭해라
        # 다음장 클릭
        click_next_page(driver)

print(dict)

# 파일저장
# 판다스 데이터프레임으로 만들기 : 엑셀(테이블) 형식으로 만들기
import pandas as pd

df = save_to_csv(dict, keyword)
save_img(df)

 

6. 결과

저장된 이미지

결과적으로 이미지와 데이터가 잘 저장된 것을 확인할 수 있습니다~~

이미지는 저작권 때문에 개인적으로 확인해보세요 ^&^

Comments