원하는 웹사이트를 크롤링 해보자!

Hyeyeon Kim·2024년 8월 25일
0

서비스 운영 중 소비자 층의 이야기를 실시간으로 모니터링하고 싶어
커뮤니티 글을 크롤링하는 프로그램을 제작하게 되었다.

1. 환경 세팅

가상환경을 만들어 jupyter notebook에서 코드를 작성할 것이다.

conda create -n [가상환경 이름]        --가상환경 생성
conda activate [가상환경 이름]         --가상환경 실행
conda deactivate [가상환경 이름]       --가상환경 종료

jutyter notebook  --쥬피터 실행

2. 기본 코드 작성

selenium과 webdriver_manager를 이용하기 위해 미리 install 받았다.

!pip install selenium
!pip install webdriver_manager
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))

driver.get("사이트 링크")

여기까지 작성 후에 코드를 실행 시 크롬 창 잘 켜진다면 성공이다.

F12 개발자 모드로 원하는 데이터의 selector를 선택해 다음과 같이 정보를 가져오면 된다.

elements = driver.find_elements(By.CSS_SELECTOR, "tbody.listwrap2 tr")

3. 응용

이제 아래는 현재 서울의 날짜를 가져와 현재 시간에서 1시간 이전에 작성 된 모든 글을 가져와
json형태로 데이터를 가져오는 식으로 작성된 코드이다

from datetime import datetime, timedelta
import json
import time
import pytz

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

# 시간 설정
seoul_tz = pytz.timezone('Asia/Seoul')
now = datetime.now(seoul_tz)
one_hour_ago = now - timedelta(hours=1)

# 언더플로우 처리: 0시에서 1시간 전은 전날 23시
if one_hour_ago.hour == 23 and now.hour == 0:
    today = (now - timedelta(days=1)).strftime('%Y-%m-%d')
else:
    today = one_hour_ago.strftime('%Y-%m-%d')

target_time = one_hour_ago.strftime('%H')

def handler(event=None, context=None):
    chrome_options = webdriver.ChromeOptions()
    chrome_options.binary_location = "/opt/chrome/chrome"
    chrome_options.add_argument("--headless")
    chrome_options.add_argument('--no-sandbox')
    chrome_options.add_argument("--single-process")
    chrome_options.add_argument("--disable-dev-shm-usage")
    chrome_options.add_argument("user-agent=Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
    chrome_options.add_argument('window-size=1392x1150')
    chrome_options.add_argument("disable-gpu")

    service = Service(executable_path="/opt/chromedriver")
    driver = webdriver.Chrome(service=service, options=chrome_options)
    
    result_data = []
    
	for i in range(1, 4):
    	driver.get(f"https://gall.dcinside.com/mgallery/board/lists/?id=tgijjdd&page={i}")
        elements = driver.find_elements(By.CSS_SELECTOR, "tbody.listwrap2 tr")

		for index in range(len(elements)):
        	elements = driver.find_elements(By.CSS_SELECTOR, "tbody.listwrap2 tr")
            element = elements[index]

			data_type = element.get_attribute('data-type')
            date_title = element.find_element(By.CLASS_NAME, 'gall_date').get_attribute('title')
            date_time_parts = date_title.split(' ')
            date = date_time_parts[0]

			# 1시간 전의 날짜와 시간이 일치하는 글만 필터링
            if (data_type != "icon_notice" and data_type is not None) and date == today and date_time_parts[1][:2] == target_time:
            	# 게시물 링크 가져오기
                url = element.find_element(By.TAG_NAME, "a").get_attribute('href')    

				element.find_element(By.CSS_SELECTOR, "td.gall_tit.ub-word > a").click()
                ele = driver.find_element(By.CSS_SELECTOR, "div.write_div")
                title = driver.find_element(By.CSS_SELECTOR, "span.title_subject")
                result_data.append({
                	"title": title.text,
                	"content": ele.text,
                	"url": url
                })
                driver.back()
     	time.sleep(5)
        
    driver.quit()
	print(result_data)

if __name__ == '__main__':
    handler()
profile
성장하고 싶은 백엔드 주니어 개발자

0개의 댓글