Python

[일단!] 데이터가 필요하다면? - 크롤링(Crawling)

myqzq 2025. 2. 8. 05:18

[일단!] - 일단 실행해보세요! 멋진일이 일어날걸요?

[알고!] - 코드 로직과 필요한 개념들을 같이 정리해봐요!

 

처음부터 기본부터 시작하면 다소 지루할 것 같아서, 국비수업을 들으며 가장 멋있다고 느꼈던 크롤링 예제를 먼저 다뤄보려고 합니다😎

간단 코드 로직 설명

아래 코드는 네이버 지식인 페이지에서 원하는 기간의 게시글을 자동으로 크롤링하는 프로그램입니다. 주요 로직은 다음과 같습니다.

 

1. 날짜 범위 설정

  • 사용자가 입력한 시작일과 종료일 사이의 날짜를 계산하고, 한 번에 몇 일씩 검색할지(검색 간격)를 정합니다.
  • 이 값에 따라 검색할 날짜 범위를 나누어, 지정한 기간 전체에 대해 여러 번 검색을 진행합니다.

2. 웹드라이버 설정

  • Selenium의 Chrome 웹드라이버를 사용해 자동으로 브라우저를 제어합니다.
  • 실행 시 브라우저가 최대화된 상태로 열리고, 테스트가 끝난 후에도 바로 닫히지 않도록 설정되어 있습니다.

3. 검색 및 데이터 수집

  • 설정한 날짜 범위와 검색어를 URL에 포함시켜 네이버 지식인 검색 결과 페이지에 접속합니다.
  • 페이지에 나열된 게시글들을 하나씩 클릭해 들어가서, 질문 내용, 자세한 질문, 답변 개수, 그리고 답변 내용을 수집합니다.
  • 수집된 정보는 CSV 파일에 저장됩니다.

4. 결과 저장

  • 크롤링한 결과는 파이썬 파일이 있는 폴더 안에 자동으로 생성되는 downloads 폴더에 CSV 파일로 저장됩니다.
  • 파일 이름에는 검색어와 날짜 정보가 포함되어 있어 나중에 쉽게 찾을 수 있습니다.

 

코드를 실행하면 위와 같이 웹페이지가 열리고, 자동으로 검색 및 게시글 조회가 진행됩니다. 당황하지 마시고 잠시 기다리시면, 조사한 내용이 CSV 파일로 저장되어 있는 것을 확인할 수 있을 거예요.

 

자세한 이야기는 다음글에서!

 

아참! 저는 아직 초보 개발자라 부족한 점이 많습니다. 개선해야 할 부분이나 아이디어가 있으시면 꼭 알려주세요!!

 

# requirements.txt

selenium
webdriver_manager
pandas
import os
import time
import datetime as dt
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
import pandas as pd

def naver_kin(search, start_date, end_date, page_num=1, step_num=0, save_path="downloads"):
    error_n = 0
    step_num -= 1
    start_date_tmp = start_date
    end_date_tmp = end_date
    search_date_length = (dt.datetime.strptime(end_date, "%Y-%m-%d") - dt.datetime.strptime(start_date, "%Y-%m-%d")).days + 1
    end_date = (dt.datetime.strptime(start_date, "%Y-%m-%d") + dt.timedelta(days=step_num)).strftime("%Y-%m-%d")
    
    # Chrome 옵션 및 드라이버 설정
    options = Options()
    options.add_experimental_option('detach', True)
    options.add_argument('--start-maximized')
    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service, options=options)
    
    # 시작날짜와 끝날짜를 계산해서 step_num에 맞게 끊어주는 부분
    if int(search_date_length / (step_num+1) * 100) % 100 != 0:
        search_repeat = int(search_date_length / (step_num+1)) + 1
    else:
        search_repeat = int(search_date_length / (step_num+1))
    
    # 지정한 저장 경로가 없으면 생성하기 위해
    if not os.path.exists(save_path):
        os.makedirs(save_path)
    
    res = [{"질문":""}]
    
    # 크롤링 시작!
    for i in range(search_repeat):
        for page in range(1, page_num+1):
            url = f'https://kin.naver.com/search/list.nhn?sort=date&section=kin&query={search}&period={start_date}%7C{end_date}&page={page}'
    
            driver.get(url)
            time.sleep(1)
            
            for list_num in range(1,11):
                try:
                    tmp={}
                    driver.find_element(By.XPATH,f'//*[@id="s_content"]/div[3]/ul/li[{list_num}]/dl/dt/a').click()
                    time.sleep(1)
                    driver.switch_to.window(driver.window_handles[-1])
                    time.sleep(1)
                    tmp['질문'] = driver.find_element(By.XPATH,'//*[@id="content"]/div[1]/div[1]/div[1]').text.replace('질문\n','')
                    tmp['상세질문'] = driver.find_element(By.XPATH,'//*[@id="content"]/div[1]/div[1]/div[3]').text.replace('\n','')
                    tmp['답변개수'] = driver.find_element(By.XPATH,'//*[@id="content"]/div[1]/div[7]/div[1]/div/div/div[1]/span').text
                    tmp['답변'] = [i.text for i in driver.find_elements(By.CLASS_NAME,'se-component-content')]
                    driver.close()
                    driver.switch_to.window(driver.window_handles[-1])
                    time.sleep(1)
                    if tmp['질문'] == res[-1]['질문']:
                        break
                    res.append(tmp)
                except:
                    print(f"{page}페이지 {list_num}번째 자료 오류로인하여 수집되지 않았습니다.")
                    error_n += 1
        start_date = (dt.datetime.strptime(end_date,"%Y-%m-%d") + dt.timedelta(days=1)).strftime("%Y-%m-%d")
        end_date = (dt.datetime.strptime(start_date,"%Y-%m-%d") + dt.timedelta(days=step_num)).strftime("%Y-%m-%d")
        if dt.datetime.strptime(end_date,"%Y-%m-%d") >= dt.datetime.strptime(end_date_tmp,"%Y-%m-%d"):
            end_date = end_date_tmp
    
    # 드라이버 종료
    driver.quit()
    
    # 크롤링 결과를 DataFrame으로 변환 후 CSV 파일로 저장
    res = res[1:]
    df = pd.DataFrame(res)
    filename = f'네이버지식인_{search}_{start_date_tmp}_{end_date_tmp}_{page_num}.csv'
    file_path = os.path.join(save_path, filename)
    df.to_csv(file_path, index=False, encoding='utf-8-sig')
    
    return filename

if __name__ == "__main__":
    search = "개발자"
    start_date = "2025-02-01"
    end_date = "2025-02-02"
    page_num = 1
    step_num = 1
    save_path = "downloads"
    file_path = naver_kin(search, start_date, end_date, page_num, step_num, save_path)
    print(f'{file_path}가 생성되었습니다!')
# 파라미터 설정안내

# 검색어
search = "아이폰"
# 시작날짜
start_date = "2025-02-01"
# 끝날짜
end_date = "2025-02-02"
# 해당일자에 검색하고자하는 페이지수
page_num = 1
# 날짜단위(예를들어 1이면 1일씩 끊어서 수집, 2면 2일씩 끊어서 수집 - 데이터의 양에따라 조절)
step_num = 1
# 다운로드 폴더경로
save_path = "downloads"

 

수집내용

질문, 상세질문, 답변개수, 답변(리스트)

 

크롤링을 할때는 서비스 정책(서비스 약관 등)을 꼭 확인해보시기바랍니다!

참고 : https://kin.naver.com/robots.txt