Skip to content

Latest commit

 

History

History
152 lines (129 loc) · 5.51 KB

211005.md

File metadata and controls

152 lines (129 loc) · 5.51 KB

Day 4

직장인을 위한 데이터분석 with 파이썬 (4일차)

인스타그램 크롤링

인스타그램 검색 결과 URL 만들기 함수화

def insta_searching(word):
    url = 'https://www.instagram.com/explore/tags/' + word
    return url

첫 번째 게시글 열기 함수

def select_first(driver):
    first = driver.find_element_by_css_selector('div._9AhH0')
    first.click()
    time.sleep(3)

게시글 정보 가져오기 함수

import re
from bs4 import BeautifulSoup
import unicodedata

def get_content(driver):
    # 현재 페이지의 HTML 정보 가져오기
    html = driver.page_source
    soup = BeautifulSoup(html, 'html.parser')
    
    # 본문 내용 가져오기
    try:
        content = soup.select('div.C4VMK > span')[0].text
        content = unicodedata.normalize('NFC', content) 
        # macOS에서 작성된 글에서 한글 자음과 모음이 분리되는 현상이 확인되어 한글 자음과 모음을 합쳐서 한글을 처리하도록 함
    except:
        content = ' '
    
    # 본문 내용에서 해시태그 가져오기(정규식 활용)
    tags = re.findall(r'#[^\s#, \\]+', content)
    
    # 작성일자 정보 가져오기
    date = soup.select('time._1o9PC.Nzb55')[0]['datetime'][:10] # BeautifulSoup에서는 여러 개의 class명을 지정할 경우 공백을 점으로 변경해서 지정 가능
    
    # 좋아요 수 가져오기
    try:
        like = soup.select('div.Nm9Fw > a > span')[0].text
    except:
        like = 0
        
    # 위치정보 가져오기
    try:
        place = soup.select('div.M30cS')[0].text
        place = unicodedata.normalize('NFC', place)
    except:
        place = ''
    
    #수집한 정보 저장하기
    data = [content, date, like, place, tags]
    return data

다음 게시글 열기 함수

def move_next(driver):
    right = driver.find_element_by_css_selector('a.coreSpriteRightPaginationArrow')
    right.click()
    time.sleep(3)

최종 코드

from selenium import webdriver
from bs4 import BeautifulSoup
import time
import re
import pandas as pd

# 크롬 브라우저 열기 및 로그인 하기
driver = webdriver.Chrome('c:/webdriver/chromedriver.exe')
driver.get('https://www.instargram.com')
time.sleep(2)

# 로그인 과정 진행
email = '<id>' # 계정 정보 수정 필요
input_id = driver.find_elements_by_css_selector('input._2hvTZ.pexuQ.zyHYP')[0]
input_id.clear()
input_id.send_keys(email)

password = '<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(3)

# 인스타그램 검색 페이지 URL 만들기
word = '제주도맛집' # 검색어
url = insta_searching(word)

# 검색 페이지 접속하기
driver.get(url)
time.sleep(10)

# 첫 번째 게시글 열기
select_first(driver)

# 비어 있는 변수(results) 만들기
results = []

# 여러 게시물 수집하기
target = 500 # 크롤링할 게시글 수
for i in range(target):
    # 게시글 수집에 오류 발생 시(네트워크 문제 등의 이유로) 2초 대기 후
    # 다음 게시글로 넘어가도록 try, except 구문 활용
    try:
        data = get_content(driver) # 게시글 정보 가져오기
        results.append(data)
        move_next(driver)
    except:
        time.sleep(2)
        move_next(driver)
        
results_df = pd.DataFrame(results)
results_df.columns = ['content','date','like','place','tags']
results_df.to_excel('./files/1_crawling_jejudoMatJip.xlsx', index = False)

정규 표현식

특정한 규칙을 가진 문자열의 패턴을 표현하는 데 사용하는 표현식

re모듈을 import 해줘야한다

search() : 특정 문자열을 검색하여 처음 맞는 문자열을 리턴, 있으면 MatchObject 리턴, 없으면 None 리턴

findall() : 매칭되는 모든 결과 리스트로 리턴
ex) re.findall(r'패턴 문자열', '문자열')

패턴 설명 예제
^ 이 패턴으로 시작 ^abc : abc로 시작해야함 (abcd, abc12 등)
$ 이 패턴으로 종료 xyz$ : xyz로 종료되어야 함 (123xyz, strxyz 등)
[문자들] 문자들 중에 하나이어야 함. 가능한 문자들의 집합을 정의함 [Pp]ython : "Python" 혹은 "python"
[^문자들] [문자들]의 반대로 피해야할 문자들의 집합을 정의함. [^aeiou] : 소문자 모음이 아닌 문자들
| 두 패턴 중 하나이어야 함(or 기능) a|b : a 또는 b 이어야 함
? 앞 패턴이 없거나 하나이어야 함 (Optional 패턴을 정의할 때 사용) \d? : 숫자가 하나 있거나 없어야 함
+ 앞 패턴이 하나 이상이어야 함 \d+ : 숫자가 하나 이상이어야 함
* 앞 패턴이 0개 이상이어야 함 \d* : 숫자가 없거나 하나 이상이어야 함
패턴{n} 앞 패턴이 n번 반복해서 나타나는 경우 \d{3} : 숫자가 3개 있어야 함
패턴{n, m} 앞 패턴이 최소 n번, 최대 m번 반복해서 나타나는 경우 \d{3,5} : 숫자가 3개, 4개 혹은 5개 있어야 함
\d 숫자 0~9 \d\d\d : 0~9 범위의 숫자가 3개를 의미(123, 000 등)
\w 문자를 의 \w\w\w : 문자가 3개를 의미 (xyz, ABC 등)
\s 화이트 스페이스를 의미하는데, [\t\n\r\f]와 동일 \s\s : 화이트 스페이스 문자 2개 의미 (\t\n, \t\t 등)
. 뉴라인(\n)을 제외한 모든 문자를 의미 .{3} : 문자 3개 (F15, 0x0 등)