본문 바로가기
Programming/Code Archive

[파이썬Python] 인스타그램 해쉬태그(#) 검색결과 크롤링하기

by 지표덕후 2021. 2. 21.

댓글로 주신 의견 반영하여 코드는 지속적으로 수정하고 있습니다. 수정된 부분은 아래 본문에 일일이 표시해두었으니 참고해주세요. 댓글 주신 모든 분들 감사합니다.

 

★ Meta에서 인스타그램 마크업을 계속 수정하는지 오늘 되던 코드가 내일 안 되는 일이 비일비재합니다. 이미 누더기가 된 코드를 다시 수정하는 게 의미가 없을 듯하여 오늘(2022/08/13) 시점에 제대로 작동하는 코드를 별도의 페이지에 작성했습니다. 이후에는 코드 작동 안 한다는 댓글에 응대하기 힘들 듯합니다. 양해 부탁드립니다.

 

[파이썬] 인스타그램 해쉬태그(#) 검색결과 크롤링하기_최신ver.

인스타그램 해쉬태그 검색결과 크롤링하는 코드를 올렸었어요, 감사하게도 많은 분들이 참고해주셨는데 Meta에서 마크업을 계속 수정하다보니까 코드가 작동 안 한다는 민원이 계속 접수되더군

mokeya.tistory.com

 

셀레니움의 기초


이 포스팅에서 소개하는 크롤링은 파이썬 Selenium 라이브러리를 사용합니다. 그러니 셀레니움에 대한 기초가 없는 분들은 아래 포스팅을 먼저 읽어보셔요.

 

 

미국 주식 재무제표 크롤링으로 배우는 파이썬 Selenium 기초

웹 크롤링(혹은 웹 스크래핑)을 하는 여러 가지 방법 중에 파이썬 셀레니움을 활용하는 방식은 난이도가 좀 있는 편입니다. 저 역시 가급적 Selenium 없이 크롤링 하는 걸 선호하지만 어떤 유형의

mokeya.tistory.com

 

 

 

코딩의 결과


기본 컨셉은, 인스타그램에서 특정 해시태그를 검색했을 때 나오는 게시물들을

나 대신 하나하나 누르면서 게시물 내의 정보를 긁어오는 머신을 만든다고 생각하시면 됩니다.

게시물을 긁어와랏, 머신!

 

 

 

 

이 작업으로 수집하는 정보는 인스타그램 게시물 본문과 게시일, 좋아요 수, 장소, 해시태그입니다.

아래와 같은 형태의 테이블로 저장되고 엑셀로 읽기, 쓰기가 가능합니다.

순번 content date like place tags
0 저녁에 뭘할까? 하다 잡채가 급 땡기네~냉장고에 시금치와 느타리버섯 조금남은것 양파 당근 있고 고기가없네 ㅋ 떡볶이 만들려고 사놓은 사각어묵이  있어 어묵잡채로 ~~#집밥 #맛스타그램 #어묵잡채 #요즘시금치가맛있다 #잡채 #foodstagram #cookstagram #koreanfood 2021-01-22 5,423 Koreatown, Los Angeles ['#짚신매운갈비찜', '#spicyfood', '#매운갈비찜', '#갈비찜', '#kfood짚신매운갈비찜', '#Canada', '#koreanfood']

 

 

작업환경


1) 파이썬3.7(32bit)

2) 파이썬IDE는 JetBrain의 Pycharm

3) 크롤링 머신은 크롬 확장 프로그램의 도움으로 작동하기 때문에 사전에 크롬이 설치되어 있어야 합니다.

4) 또한 크롬드라이버(ChromeDriver)라는 파일(.zip)을 다운받아서 앞으로 작성할 파이썬 코드(.py)가 저장될 폴더에 함께 넣어두어야(=압축 해제) 합니다.

  ① 먼저 우리 크롬 브라우저의 버전을 확인합니다.

       크롬 브라우저 우상단의 메뉴 > 도움말 > Chrome정보(아래 스샷 참고)

 

② 아래 링크된 페이지에서 우리 버전 및 운영체제에 맞는 크롬 웹드라이버를 다운 받습니다.

https://chromedriver.chromium.org/downloads

 

③ 다운 받은 압축파일의 내용물을 코드가 저장된() 폴더에 압축 해제합니다.

 

 

코드

* 2022/04/03 게시물 크롤링 함수 정의하는 코드 스니펫 수정


크롤링에 필요한 여러 패키지들을 불러옵니다.

저혼자 인스타 로그인해서 게시물을 일일이 눌러가며 데이터를 긁어오는 이 똘똘한 머신은

셀레니움 패키지(+ 크롬 웹드라이버)가 있기에 가능한 겁니다.

# 필요 패키지 호출
from selenium import webdriver
from bs4 import BeautifulSoup
import time
import re
import time

 

 

 

 

금번 파이썬 코딩은 머신이 수행할 행동 하나하나를 분절적으로 나누어서

부분동작을 별개의 함수로 정의하는 것에서 시작합니다(국민체조 드립을 치고 싶지만 참습니다).

먼저, 내가 원하는 키워드를 받아서

해당 키워드 검색 결과 페이지의 url을 생성(반환=return)하는 함수를 정의.

# 함수 정의: 검색어 조건에 따른 url 생성
def insta_searching(word):
    url = "https://www.instagram.com/explore/tags/" + str(word)
    return url

 

 

 

 

다음으로, 검색 결과 페이지에서 첫 번째 게시물을 클릭하는 함수를 정의.

인스타그램 서버에서 우리 머신이 (무언가 불순한 의도를 가지고) 마우스를 갈기는 것처럼 인식되지 않도록,

또 데이터를 긁어오는 시간을 충분히 확보할 수 있도록,

다음 행동과의 시차를 time.sleep() 메서드로 구현.

# 함수 정의: 열린 페이지에서 첫 번째 게시물 클릭 + sleep 메소드 통하여 시차 두기
def select_first(driver):
    first = driver.find_elements_by_css_selector("div._9AhH0")[0]
    first.click()
    time.sleep(3)

 

 

 

 

클릭해 들어간 게시물에서 내가 원하는 정보,

본문 내용과 작성일자, 좋아요 수, 위치 정보, 해시태그를 가져오는 함수 정의.

인스타의 프론트 코드가 변경되어 '좋아요 수'가 수집되지 않는 오류를 정정(2021/08/20)

인스타 마크업의 selector가 변경되어 몇몇 정보가 수집되지 않는 오류 정정(2022/04/03)

# 함수 정의: 본문 내용, 작성일자, 좋아요 수, 위치 정보, 해시태그 가져오기
## 2022/04/03 전체적으로 수정
import re
from bs4 import BeautifulSoup

def get_content(driver):
    html = driver.page_source
    soup = BeautifulSoup(html, 'lxml')
    # 본문 내용
    try:
        content = soup.select('div.MOdxS')[0].text
    except:
        content = ''
    # 해시태그
    tags = re.findall(r'#[^\s#,\\]+', content)
    
    # 작성일자
    date = soup.select('time._1o9PC')[0]['datetime'][:10]
    
    # 좋아요
    try:
        like = soup.select('section.EDfFK.ygqzn')[0].findAll('span')[-1].text
    except:
        like = 0
    # 위치
    try:
        place = soup.select('div.M30cS')[0].text
    except:
        place = ''

    data = [content, date, like, place, tags]
    return data

 

 

 

 

한 게시물에서 소기의 목적을 달성(=원하는 정보 긁어오기)한 후

다음 게시물로 넘어가는(= 게시물 오른쪽의 화살표 클릭하여 페이징) 함수 정의.

time.sleep() 메서드로 마찬가지로 다음 행동과의 시차를 확보.

다음 게시물로 넘어가는 버튼의 프론트 코드가 변경되어 이를 반영하였습니다(2022/01/11).

# 함수 정의: 첫 번째 게시물 클릭 후 다음 게시물 클릭
def move_next(driver):
    right = driver.find_element_by_css_selector("div.l8mY4.feth3") # 2022/01/11 수정
    right.click()
    time.sleep(3)

 

 

 

 

아래 코드는 본격적으로 머신에게 일을 시키는 코드입니다.

위에서 정의한 각 부분동작(=함수)들이 포함되어 있습니다.

다만 함수로 정의하지 않은 몇 가지 행동들은 별도로 코딩을 해야 하는데,

가령. 최초에 인스타그램에 접속하여 로그인을 하기 위한 코드라라든지

검색어를 입력 받는 코드(아래 스샷), 크롤링 할 게시물의 수를 정해주는 코드 같은 것들입니다.

 

코드를 수행하면 인스타그램 메인이 뜨면서 자동으로 로그인이 되고,

위와 같이 검색 키워드를 입력하면,

이제 머신이 순차적으로 부분동작을 수행하면서

게시물 하나하나의 데이터를 정성스럽게 긁어(크롤링)올 겁니다.

페이지가 완전히 로드된 후 첫 게시물을 클릭할 수 있도록 sleep()의 파라미터 수정(2022/01/11).

# 크롤링 시작
"""
driver.get(url)을 통해 검색 페이지 접속하고,
target 변수에 크롤링할 게시글의 수를 바인딩
"""

# 크롬 브라우저 열기
driver = webdriver.Chrome('chromedriver.exe')

driver.get('https://www.instagram.com')
time.sleep(3)

# 인스타그램 로그인을 위한 계정 정보
email = '인스타그램 로그인 아이디'
input_id = driver.find_elements_by_css_selector('input._2hvTZ.pexuQ.zyHYP')[0]
input_id.clear()
input_id.send_keys(email)

password = '인스타그램 로그인 비번'
input_pw = driver.find_elements_by_css_selector('input._2hvTZ.pexuQ.zyHYP')[1]
input_pw.clear()
input_pw.send_keys(password)
input_pw.submit()

time.sleep(5)

# 게시물을 조회할 검색 키워드 입력 요청
word = input("검색어를 입력하세요 : ")
word = str(word)
url = insta_searching(word)

# 검색 결과 페이지 열기
driver.get(url)
time.sleep(8) # 코드 수행 환경에 따라 페이지가 로드되는 데 시간이 더 걸릴 수 있어 8초로 변경(2022/01/11)

# 첫 번째 게시물 클릭
select_first(driver)

# 본격적으로 데이터 수집 시작
results = []
## 수집할 게시물의 수
target = 10000
for i in range(target):

    try:
        data = get_content(driver)
        results.append(data)
        move_next(driver)
    except:
        time.sleep(2)
        move_next(driver)

print(results[:2])

 

 

 

 

부디 코드가 정상적으로 작동하여 크롤링 무사히 마치고,

데이터가 예쁘게 들어간 엑셀 파일 떡하니 생성되어 있길 바랍니다.

# 결과를 데이터프레임으로 저장
# 2022/04/03 수정
import pandas as pd
from datetime import datetime

date = datetime.today().strftime('%Y-%m-%d')

results_df = pd.DataFrame(results)
results_df.columns = ['content','date','like','place','tags']
results_df.to_excel(date + '_about '+word+' insta crawling.xlsx')

이번 크롤러 제작에 사용한 셀레니움 패키지를 조금만 응용하면 마케팅에 활용할 수 있는 다양한 데이터를 수집할 수 있습니다. 가령 아래처럼요:

파이썬 웹스크래핑: 구글 플레이 스토어 앱 리뷰 크롤링

댓글