본문 바로가기
정리/정보 요약

[정보] 인스타 크롤링 해보기

by 멘멘 2021. 7. 20.

인스타그램 크롤링 순서도

 

1. 크롬 브라우저 열기 -> 인스타 검색페이지 url 만들기 -> 검색페이지 접속하기 -> 첫게시글 클릭하기

(인스타 로그인은 수동 필요...)

from selenium import webdriver
driver = webdriver.Chrome('드라이버 위치')
import time

#인스타 접속
driver.get('https://www.instargram.com')
time.sleep(2)

#검색 함수
def insta_searching(word):
	url = 'https://www.instagram.com/explore/tags/' + word
    return url
    
word = '충남삼성고'
url = insta_searching(word)
driver.get(url)

#첫 게시글 클릭
def select_first(driver):
	first = driver.find_element_by_css_selector("div._9AhH0")
    #elements의 경우 list로 반환됨
    #함수로 사용되어지므로, 호출될때마다 하나씩 클릭하면 됨
    first.click()
    time.sleep(3)
    
 select_first(driver)

 

2. 비어있는 변수 만들기 - > 게시글 정보 가져오기(get_content) ->게시글 정보 추가 

import re
from bs4 import BeautifulSoup
import unicodedata #macOs에서 작성되었을시 한글 자음/모음 분리현상  -> 자음모음 합치기 위함

def get_content(driver):
	# 1) 현재페이지 html 정보 가져오기
	html = driver.page_source
	soup = BeautifulSoup(html,'lxml')
	# 2) 본문 내용 가져오기
	try:
		content = soup.select('div.C4VMK > span')[0].text
		content = unicodedata.normalize('NFC',content)
	except: #에러 발생시 실행
		content = ''

	# 3) 본문 내용에서 해시태그 가져오기
	# #으로 시작하고 #뒤 연속된 문자를 모두 찾아서 리스트 형태로 저장
	tags = re.findall(r'p^\s#,\\]+',content)

	# 4) 작성일자 정보 가져오기
	date = soup.select('time.10~~')[0]['datetime'][:10]

	# 5) 좋아요 수 가져오기
	try:
		like = soup.select('div.Nm9Fw > a > span')[0].text
	except:
		like = 0
	# 6) 수집한 정보 저장하기
	data = [content,data,like,tags]
	return data

#첫 게시글만 출력해보기
data = get_content(driver)
import pandas as pd
result = pd.DataFrame(Data)
result.columns = ['content']
print(result)​

 

3. 다음페이지 함수(move_next) -> 2번 반복 -> 수집완료

def move_next(driver):
	right = driver.find_element_by_css_selector('a.coreSpriteRightPaginationArrow')
    right.click()
    time.sleep(3)
    
#게시글 수집
results = []
target = 50 #크롤링할 게시글 수 
for i in range(target):
#게시글 수집 오류 발생 시 2초 대기후 넘김
	try:
    	data = get_content(driver)
        results.append(data)
        move_next(driver)
    except:
    	time.sleep(2)
        move_next(driver)
        
#print(results[:2]) #출력해보기

#엑셀저장
impoer pandas as pd
results_df = pd.DataFrame(results)
results_df.columns = ['content','data','like','tags']
results_df.to_excel('1_datacrawling.xlsx')

 

4. 다양한 형태로 저장한 엑셀 데이터 합치기

import pandas as pd
insta_df = pd.DataFrame([]) #데이터프레임 초기값 설정

folder = './files/'
f_list = ['1_datacrwaling.xlsx','2_datacrwaling.xlsx','3_datacrwaling.xlsx','4_datacrwaling.xlsx']
for fname in f_list:
	fpath = folder + fname
    temp = pd.read_excel(fpath)
    insta_df = insta_df.append(temp)
    
insta_df.columns = ['content','data','like','place','tags']

#게시글 본문 동일시 중복 제거 / inplace = True ->원본 데이터 변경
insta_df.drop_duplicates(subset = ["content"], inplace = True)
insta_df.to_excel('./files/1_rawcrawling.xlsx',index = False)

 

5. 태그 빈도수 집계

import pandas as pd
raw_total = pd.read_excel('1_rawcrawling.xlsx')
raw_total['tags'][:3]

# tags에서 []를 제외하고 ",띄어쓰기"를 기준으로 #내용 가져오기
tags_total = []

for tags in raw_total['tags']: 
	tags_list = tags[2:-2].split(''', ''') #,띄어쓰기 기준으로 나누기
    for tag in tags_list:
    	print(tag)
        tags_total.append(tag)
        
from collections import Counter
tag_counts = Counter(tags_total) #집계
tag_counts.most_common(50) #가장 많이 언급된 해시태그 ('#룰루', 50) 형태로 출력됨

#무관한 해시태그 제외
STOPWORDS = ['#일상','#선팔','#소통','#맞팔']

tag_total_selected = []
for tag in tags_total:
	if tag not in STOPWORDS:
    	tag_total_selected.appeng(tag) #STOPWORDS에 포함되지 않은 해시태그만
        
tag_counts_selected = Counter(tag_total_selected)
tag_counts_selected.most_common(50)

collections. Counter

Counter() 집계

most_common() 가장 많이 언급된 해시태그

 

 

6. 막대차트로 나타내기

import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib import font_manager,rc
import sys

#운영체제 별 글꼴 설정
if sys.platform in ['win32','win64']:
	font_name = "malgun gothic"
elif sys.platform == "darwin":
	font_name = "AppleGothic"
    
 rc('font',family=font_name)
 
 #데이터 준비
 tag_counts_df = pd.DataFrame(tag_counts_selected.most_common(30))
 tag_counts_df.columns = ['tags','counts']
 
 #막대 차트 그리기
 #sns.barplot()은 seaborn의 막대차트를 그리는 함수임
 plt.figure(figsize = (10,8))
 sns.barplot(x='counts', y='tags', data=tag_counts_df)

이런 느낌으로 출력됨

 

7. 워드클라우드로 나타내기

 

import matplotlib.pyplot as plt
from wordcloud import WordCloud #에러시 !pip install wordcloud
import platform

#운영체제 별 글꼴 설정
#워드클라우드에서는 글꼴의 경로를 직접 지정해야 한다
if platform.system() == 'Windows':
	font_path = "c:/Windows/Fonts/malgun.ttf"
elif platform.system() == "Darwin":
	font_path = "/Users/$USER/Library/Font/AppleGothic.ttf"
    
 
 wordcloud = WordCloud(font_path = font_path, background_color = "white", max_words = 100, relative_scaling = 0.3, width = 800, height = 400).generate_from_frequencies(tag_counts_selected)
 plt.figure(figsize = (15,10))
 plt.imshow(wordcloud)
 plt.axis('off')
 plt.savefig('./files/2_tag-wordcloud.png')

WordCloud의 generate_from_frequencies()함수로 생성

 

- background_color : 배경색

- max_words : 최대 단어 수

- relative_scaling : 워드클라우드 내 글자들의 상대적 크기

(최소 0 최대 1, 0에 가까울수록 순위, 1에 가까울수록 빈도수에 큰 영향을 보임)

- width와 height는 가로 세로 이미지 크기

- plt.figure(figsize(15,10))은 최종 출력물 크기로, 출력물 크기가 크지만 width와 height가 그만큼 높지 않다면 글자가 흐릿하게 나타날 수 있음

- 워드 클라우드는 실행 때마다 배치, 색상이 무작위

- plt.axis('off')는 눈금을 나타내지 않는다는 의미

 

'정리 > 정보 요약' 카테고리의 다른 글

[정보] 정규식 표현  (0) 2021.07.20
[정보] 동적 웹 크롤링  (0) 2021.07.20
[정보] 정적 웹크롤링  (0) 2021.07.19

댓글