Python

Python 실습 - 셀레니움으로 크롤링(이었던것)

UserDonghu 2023. 9. 24. 17:36

파이썬 처음 공부할 때 셀레니움으로 크롤링 했던것을 다시 한번 살펴보자

혼자 열심히 구글과 고군분투해서 뿌듯했던 기억이 있다.

물론 지금 보면 코드가 맘에 안든다.

 

핫딜 게시판을 크롤링해서 csv파일에 중복된 항목이 나올 때 까지 페이지를 넘겨가며 csv파일에 저장하는 방식이다.

 

 

모듈 import

많은 import들.. 셀레니움은 크롬드라이버가 계속 속을 썩여서 BeautifulSoup이 더 편한것 같다..

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.keys import Keys
import csv

크롬 드라이버 설정들.

크롬 드라이버 버전에 신경쓰지않고 자동으로 업데이트해서 최신 버전으로 실행되도록 설정을 해놨었는데, 이게 언제부터인가 오류가 나서 안된다. 나중에 다시 찾아서 수정하는걸로.

# 크롬 드라이버 자동 업데이트을 위한 모듈
from webdriver_manager.chrome import ChromeDriverManager

# 브라우저 꺼짐 방지 옵션
chrome_options = Options()
chrome_options.add_experimental_option("detach", True)

# 불필요한 에러 메시지 삭제
chrome_options.add_experimental_option("excludeSwitches", ["enable-logging"])

# 크롬 드라이버 최신 버전 설정
service = Service(executable_path=ChromeDriverManager().install())

driver = webdriver.Chrome(service=service, options=chrome_options)

 

코드 시작

csv파일을 append모드로 열고 중복여부를 False로 기본 설정.

w = open('Web/hotdeal.csv', 'a')
writer = csv.writer(w)

IS_DUPLICATE = False

 

for문으로 주소 이동

# 웹페이지 해당 주소 이동
for i in range(3):
    if(IS_DUPLICATE):
        break
    driver.get(f"https://www.fmkorea.com/index.php?mid=hotdeal&page={i+1}")
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME,"Wrapper")))#10초까지 기다림
    webdriver.ActionChains(driver).key_down(u'\ue010').key_up(u'\ue010').perform()#페이지 끝까지 내린후에 크롤링

    elements = driver.find_elements(By.CLASS_NAME, "li_best2_pop0")
    for element in elements:
        if(IS_DUPLICATE):
            break
        title = element.find_element(By.CLASS_NAME, "title").text
        link = element.find_element(By.CLASS_NAME, "title").find_element(By.TAG_NAME, 'a').get_attribute('href')
        for j in range(len(title)):#댓글 몇개인지 없애기
            if title[len(title)-j-1] == "[":
                title = title[:len(title)-j-3]
                break
        imglink = element.find_element(By.TAG_NAME, "img").get_attribute('src')
        hotdeal_info = element.find_element(By.CLASS_NAME, "hotdeal_info").text

        hotdeal_data = []
        hotdeal_data.append(title)
        hotdeal_data.append(hotdeal_info)
        hotdeal_data.append(link)
        hotdeal_data.append(imglink)

        r = open('Web/hotdeal.csv', 'r')
        reader = csv.reader(r)
        for row in reader:
            if(row == hotdeal_data):
                IS_DUPLICATE = True
                break
        r.close()
        if(IS_DUPLICATE == False):
            writer.writerow(hotdeal_data)
            print(title)
            print(hotdeal_info)
            print(link)
            print(imglink)
            print("----------------------------------")
w.close()

조금씩 살펴보기

 

for문을 돌려서 csv파일에 중복이면 멈추고 아니면 크롤링해서 추가.

for i in range(3):
    if(IS_DUPLICATE):
        break

 

for i in range(3)이니까 최대 3페이지까지 가져오기

driver.get(f"https://www.fmkorea.com/index.php?mid=hotdeal&page={i+1}")

 

비동기 처리 처럼 데이터를 가져오는것을 최대 10초까지 기다린다.

WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.CLASS_NAME,"Wrapper")))#10초까지 기다림

 

페이지를 끝까지 내리지않으면 사진이 제대로 로딩이 안돼서 페이지를 맨 밑으로 내려서 로딩이 되도록 했다.

webdriver.ActionChains(driver).key_down(u'\ue010').key_up(u'\ue010').perform()#페이지 끝까지 내린후에 크롤링

 

셀렉터를 아직 모를때라 요소를 굉장히 힘들게 찾았다..

elements = driver.find_elements(By.CLASS_NAME, "li_best2_pop0")
    for element in elements:
        if(IS_DUPLICATE):
            break
        title = element.find_element(By.CLASS_NAME, "title").text
        link = element.find_element(By.CLASS_NAME, "title").find_element(By.TAG_NAME, 'a').get_attribute('href')
        imglink = element.find_element(By.TAG_NAME, "img").get_attribute('src')
        hotdeal_info = element.find_element(By.CLASS_NAME, "hotdeal_info").text

 

정규표현식을 몰랐어서 제목도 정리를 힘들게 했다...

for j in range(len(title)):#댓글 몇개인지 없애기
            if title[len(title)-j-1] == "[":
                title = title[:len(title)-j-3]
                break

 

배열에 추가하는것도 좀 아쉽네

hotdeal_data = []
hotdeal_data.append(title)
hotdeal_data.append(hotdeal_info)
hotdeal_data.append(link)
hotdeal_data.append(imglink)

 

csv파일을 열어서 이미 핫딜 데이터가 있으면 중복여부를 True로 바꿈

r = open('Web/hotdeal.csv', 'r')
        reader = csv.reader(r)
        for row in reader:
            if(row == hotdeal_data):
                IS_DUPLICATE = True
                break
        r.close()

 

중복여부가 False면 csv파일에 쓰기

if(IS_DUPLICATE == False):
            writer.writerow(hotdeal_data)

 

 

고칠점이 참 많지만 아직 크롬드라이버가 제대로 작동을 안해서 실행이 안된다..

제대로 작동되면 코드 한번 갈아엎는걸로.