코딩코딩코딩

인스타그램 해시태그 크롤링 및 분석 - 2 본문

파이썬/텍스트마이닝

인스타그램 해시태그 크롤링 및 분석 - 2

hanshow113 2020. 7. 23. 15:28

지난 번 내용과 이어서 해시태그와 좋아요, 날짜등을 가져오는 함수를 만들어보도록 하겠습니다.

 

SCROLL_PAUSE_TIME = 2.0
post_link = []

while True:
    pageString = driver.page_source   # page_source : 현재 렌더링된 페이지의 Elements를 모두 가져옴
    bsObj = bs(pageString, 'lxml')

    for postline in bsObj.find_all(name='div', attrs={"class":"Nnq7C weEfm"}):
        a_len = len(postline.select('a'))
        # 인스타그램 게시물은 행별로 최대 3개까지 확인할 수 있는데, 최근게시물이나 마지막 게시물은 1,2개가 나올 수도 있어서 len 지정
        for post in range(a_len):   
            item = postline.select('a')[post]
            link = item.attrs['href']
            post_link.append(link)



    last_height = driver.execute_script('return document.body.scrollHeight')   # 자바스크림트로 스크롤 길이를 넘겨줌
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")   # selenium에서 scroll 기능 사용
    time.sleep(SCROLL_PAUSE_TIME)
    # 프로세스 자체를 지정시간동안 기다려줌(무조건 지연)
    #driver.implicitly_wait(SCROLL_PAUSE_TIME)
    # 브라우저 엔진에서 파싱되는 시간을 기다려줌(요소가 존재하면 지연없이 코드 실행)
    new_height = driver.execute_script("return document.body.scrollHeight")

    if new_height == last_height:
        driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
        time.sleep(SCROLL_PAUSE_TIME)
        #driver.implicitly_wait(SCROLL_PAUSE_TIME)
        new_height = driver.execute_script("return document.body.scrollHeight")

        if new_height == last_height:
            break
        else:
            last_height = new_height
            continue

지난 번 검색 함수로 검색한 내용을 selenium을 통해 자동으로 스크롤하며 내용을 가져오는 내용입니다.

 

# 날짜 관계없이 게시물 내용 끝까지 수집

num_of_post = len(post_link)

print('총 {0}개의 게시글을 수집합니다.'.format(num_of_post))

id_list = []
like_list = []
tag_list = []
link_list = []
date_list = []
month_list = []
day_list = []

for i in tqdm_notebook(range(num_of_post)):
    
    tag_list.append([])
    
    # 개별 링크 리스트 
    link_list.append("https://www.instagram.com" + post_link[i])   
    req = Request("https://www.instagram.com" + post_link[i], headers={'User-Agent': 'Mozila/5.0'})
    postpage = urlopen(req).read()
    
    post_body = bs(postpage, 'lxml', from_encoding='utf-8')
    post_core = post_body.find('meta', attrs={'property':"og:description"})
    contents = post_core['content']

    # 시간    
    posttxt = str(postpage)    
    timestamp = int(posttxt[posttxt.find('taken_at_timestamp')+20 : posttxt.find('taken_at_timestamp')+30])
    date_list.append(datetime.fromtimestamp(timestamp).strftime('%Y/%m/%d %H:%M'))
    month_list.append(datetime.fromtimestamp(timestamp).strftime("%m"))
    day_list.append(datetime.fromtimestamp(timestamp).strftime("%d"))
    
    # 좋아요
    try:
        likes = int(contents[: contents.find(' Likes, ')])  # Likes 문자열 앞에 있는 좋아요 개수 추출
    except:
        likes=0  # 좋아요 가 아니라 조회수로 표시되는 경우도 있어 이런 경우는 0으로 표시
    like_list.append(likes)
    
    # 개별 계정
    if "@" and ")" in contents:
        personal_id = contents[contents.find("@")+1 : contents.find(")")]
    elif "@" and ")" not in contents and "on Instagram" in contents:
        personal_id = contents[contents.find("@")+1 : contents.find('on Instagram')]
    else :
        personal_id = contents[1: contents.find(' posted on')]
    id_list.append(personal_id)
    
    '''    
    (@personal_id) on instagram, @persoanlid posted on instagram, personal_id on instgram 등의 형태로 meta 데이터에 표시되기
    때문에 여러 형식별 id 추출 if문 수행
    '''
    
    # 해시태그
    for tag_content in post_body.find_all('meta', attrs={'property':"instapp:hashtags"}):
        hashtags = tag_content['content'].rstrip(',')
        tag_list[i].append(hashtags)

post_link에 저장된 게시물 링크를 순차적으로 돌면서 해시태그, 계정, 좋아요, 시간 정보 등을 가져옵니다.

 

 

insta_dict = {'날짜':date_list,
              '월':month_list,
              '일':day_list,
              '계정':id_list,
             '좋아요':like_list,
             '해시태그':tag_list,

             '링크':link_list}
df = pd.DataFrame(insta_dict)
df

크롤링해서 리스트로 만든 것들을 데이터프레임 형식으로 묶어주면 원하는 결과를 확인할 수 있습니다.

 

 

Comments