데이터 분석/Python

[텍스트 마이닝-수집] 네이버 블로그 크롤러(2) - 본문 수집

초코레모네이드 2023. 9. 17. 20:50

 


 1차 크롤러

https://chocolemon.tistory.com/137
 

 

[텍스트 마이닝-수집] 네이버 블로그 크롤러(1) - 수집할 목록 만들기

텍스트 수집 자동화는 사실 '크롤러' 라고 이름 붙이기 애매하지만, 이미 크롤러 라는 단어가 일상적으로 쓰이고 있으므로 편의상 크롤러라고 칭하겠습니다. 이전에 올린 것은 코드를 반복 실행

chocolemon.tistory.com

 


 


이제 1차로 수집한 링크의 글들을 수집할 차례입니다.
제일 먼저 필요한 패키지와 모듈을 임포트합니다.

import pandas as pd
import numpy as np
import time
from tqdm.notebook import tqdm
import random
import urllib.request
from selenium.common.exceptions import NoSuchElementException, UnexpectedAlertPresentException, TimeoutException
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
# 크롤링 차단 방지용 user-agent (임시)
import user_agent
from user_agent import generate_user_agent

 
1차와 똑같은 코드이니 설명은 생략하겠습니다.

# 웹드라이버 설정
options = webdriver.ChromeOptions()
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option("useAutomationExtension", False)
# print는 설정이 잘 됐는지 확인해보려는 것이므로 굳이 실행하지 않아도 됩니다.
# print(generate_user_agent(device_type='desktop'))
# print(generate_user_agent(os='win', device_type='desktop'))
# print(generate_user_agent(os=('mac', 'linux'), device_type='desktop'))

# 눈속임용이긴 하지만 user-agent를 설정해줍니다.
random_user = generate_user_agent(os='win', device_type='desktop')
# print(random_user)
chrome_options = Options()
chrome_options.add_argument(random_user)

 
크롬 창을 실행합니다.

driver = webdriver.Chrome(executable_path ='chromedriver.exe',options = chrome_options)
driver.maximize_window() # 창 크기 설정
driver.get("https://www.naver.com/") # 접속하고자 하는 주소 설정
time.sleep(2)

 
1차에서 수집한 링크를 불러옵니다.

df = pd.read_csv("파일경로.txt")
print(df.shape, df.columns)
df

 
글을 수집하는데 시간이 꽤 소요되기 때문에 저는 1,000개씩 나누어 수집했습니다.
만약 본인이 수집할 글이 1,000개 이하라면 안 나눠도 됩니다.

links1 = df['url'][0:1000].to_list()
links2 = df['url'][1000:2000].to_list()
links3 = df['url'][2000:].to_list()
# 숫자를 잘 적어서 나눴는지 마지막 링크 리스트 길이로 확인해봅니다.
print(len(links3))

 
이제 셀레니움으로 게시글 본문을 수집합니다.
제대로 수집되는 글만 수집해도 상관 없지만,
저는 구버전의 경우 신버전으로 작성된 블로그와 수집되는 본문의 범위가 다르기 때문에 나중에 체크하기 위해 구버전 블로그 링크를 따로 체크하기 위해 리스트에 담았습니다.
삭제/비공개 글 역시 추후 텍스트 분석 때 '게시글삭제' 를 체크해서 지워주기 위해 리스트에 담았습니다.

contents = []	# 본문 글을 담을 리스트
old_blogs = []	# 구버전 블로그 링크 담을 리스트
hide_link = []	# 삭제/비공개 처리 링크 담을 리스트

for i in tqdm(links1):
    driver.get(i)
    time.sleep(random.uniform(4,4.5))
    try:
        driver.switch_to.frame("mainFrame")
    # 시간 초과 시 적용
    except TimeoutException as e:
        print('시간 초과 오류 : ', e)
        contents.append('수집불가능')
    # 삭제/비공개 게시글 알람 뜰 때 적용
    except UnexpectedAlertPresentException as e:
        print(e)
        print('{}번째 게시글은 비공개로 전환되었거나 게시판이 바뀜.'.format(links1.index(i)))
        hide_link.append(i)
        time.sleep(1.5)
        contents.append('게시글삭제')
        continue
    try:
        a = driver.find_element(By.CSS_SELECTOR,'div.se-main-container').text
        contents.append(a)
    # NoSuchElement 오류시 예외처리(구버전 블로그에 적용)
    except NoSuchElementException:
        a = driver.find_element(By.CSS_SELECTOR,'div#content-area').text
        contents.append(a)
        old_blogs.append(i)

 
이제 수집된 본문을 데이터프레임에 담아 잘 수집됐는지 확인해봅니다.

post_df1 = pd.DataFrame({'url':links1, 'title':df['title'][0:1000], 'date':df['date'][0:1000], '본문':contents})
post_df1

 
잘 수집되었다면 원하는 파일 형태로 저장하면 끝입니다.

post_df1.to_excel("파일저장경로.xlsx", index=False) # 엑셀
post_df1.to_csv("파일저장경로.txt", index=False, encoding='UTF-8') # txt파일
post_df1.to_csv("파일저장경로.csv", index=False, encoding='UTF-8') # csv파일

 
 
 
다른 기술 블로그들이 그렇듯,
코드를 블로그에 공유하는 것은 기록과 '공유'를 위해서입니다.
만약 제 글의 도움을 받아 본인의 글을 작성하신다면 출처를 남겨주시길 바랍니다.
 
문의는 댓글로 남겨주시면 확인 후 답변드리겠습니다.
 

728x90