본문 바로가기
Python/파이썬 크롤링

쿠팡 크롤링

by 잉나영 2024. 6. 4.
반응형

쿠팡 크롤링을 해보려고 한다. 쿠팡에 있는 크림 제품 중 로켓배송만 선택하였고, 기말 프로젝트 때 사용할 상품명과 가격, 리뷰수를 크롤링해보겠다. 모든 크롤링 프로젝트는 다음 기말 때 사용할 데이터를 수집하는 과정이라고 보면 될 것 같다.

 

1. 라이브러리 불러오기

# 라이브러리 불러오기
from selenium import webdriver # 브라우저 자동화를 위한 모듈
import requests # HTTP 요청을 보내기 위한 모듈
from bs4 import BeautifulSoup as bs # HTML 내용 파싱을 위한 모듈
import pandas as pd # 데이터 조작 및 분석을 모듈
import time # 코드 실행 속도 조절을 위한 모듈
import re # 정규 표현식 사용을 위한 모듈
import pickle # 파이썬 객체 직렬화를 위한 모듈
from selenium.webdriver.common.by import By # 다양한 방법으로 엘리먼트를 찾기 위한 모듈
import datetime # 날짜와 시간 연산을 위한 모듈

 

 

2. 동적 크롤링 시작

from selenium import webdriver
from bs4 import BeautifulSoup as bs
import pandas as pd
import time

# 크롬 드라이버 로드
driver = webdriver.Chrome()

# 각 리스트 초기화
title = []  # 상품 제목 리스트
price = []  # 가격 리스트
review_cnt = []  # 리뷰 개수 리스트

driver.get('https://www.coupang.com/np/categories/486253?listSize=120&brand=&offerCondition=&filterType=rocket_luxury%2Crocket%2Ccoupang_global&isPriceRange=false&minPrice=&maxPrice=&page=10&channel=user&fromComponent=N&selectedPlpKeepFilter=&sorter=bestAsc&filter=&component=486153&rating=0&rocketAll=true')
time.sleep(3)  # 페이지가 완전히 로드될 때까지 대기

# 스크롤하여 모든 데이터를 로드
last_height = driver.execute_script("return document.body.scrollHeight")
while True:
    driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(2)  # 스크롤 후 로딩 대기
    new_height = driver.execute_script("return document.body.scrollHeight")
    if new_height == last_height:
        break
    last_height = new_height

# 페이지 소스를 가져와서 BeautifulSoup으로 파싱
soup = bs(driver.page_source, 'html.parser')

# 상품 정보 크롤링
items = soup.find_all('dl', class_='baby-product-wrap adjust-spacing')
for item in items:
    # 제목 (제품 이름)
    try:
        a = item.find('div', class_='name').get_text(strip=True)
    except:
        a = 'null'
    title.append(a)

    # 가격
    try:
        b = item.find('strong', class_='price-value').get_text(strip=True)
    except:
        b = 'null'
    price.append(b)

    # 리뷰 개수
    try:
        c = item.find('span', class_='rating-total-count').get_text(strip=True)
    except:
        c = 'null'
    review_cnt.append(c)

# 드라이버 종료
driver.quit()

# 크롤링한 데이터를 데이터프레임으로 변환
raw_data = pd.DataFrame({
    'title': title,
    'price': price,
    'review_cnt': review_cnt
})

# 결과 출력
print(raw_data)

# CSV파일로 저장
raw_data.to_csv("d10.csv", index = False, encoding="utf-8-sig")

하지만 문제가 발생하였다. 왜냐하면 쿠팡에서 크롤링을 막은 거 같아 다음 url로 넘어가는 for문 크롤링이 불가능했다. 그래서 결국 글로우픽처럼 d1~d9까지 concat을 시켜주었다.

 

d1 = pd.read_csv("d1.csv")
d2 = pd.read_csv("d2.csv")
d3 = pd.read_csv("d3.csv")
d4 = pd.read_csv("d4.csv")
d5 = pd.read_csv("d5.csv")
d6 = pd.read_csv("d6.csv")
d7 = pd.read_csv("d7.csv")
d8 = pd.read_csv("d8.csv")
d9 = pd.read_csv("d9.csv")

coopang = pd.concat([d1,d2,d3,d4,d5,d6,d7,d8,d9], ignore_index=True)

 

쨘 이렇게 coopang 크롤링을 해보았다.

 

 

하지만 이것도 전처리가 필요하다. 숫자 데이터만 필요한데 콤마와 괄호가 너무 많다.

 

3. 전처리

#숫자화
for i in range(len(coopang)):

    # price에서 숫자를 제외한 모든 문자를 삭제
    coopang['price'][i] = re.sub("[^0-9]", "", str(coopang['price'][i]))
    
    # review_cnt에서 숫자를 제외한 모든 문자를 삭제
    coopang['review_cnt'][i] = re.sub("[^0-9]", "", str(coopang['review_cnt'][i]))
    
coopang

숫자화로 변경해주고, 데이터 중 2개를 기준으로 판매하는 상품 또한 많아서 1개인 상품만 남기고 나머지는 삭제해보겠다.

 

import csv

def filter_rows(csv_file, keyword):
    filtered_rows = []
    with open(csv_file, 'r', newline='', encoding='utf-8') as file:
        reader = csv.DictReader(file)
        for row in reader:
            if keyword in row["title"]:
                filtered_rows.append(row)
    return filtered_rows

# CSV 파일 경로
csv_file = 'test_coopang.csv'

# 원하는 단어
keyword = '1개'

# 선택한 단어가 포함된 행들 추출
filtered_rows = filter_rows(csv_file, keyword)

# 결과 출력
for row in filtered_rows:
    print(row)

print(len(filtered_rows))
print(len(coopang))

coopang.csv 안에 찾을 단어를 설정해주고 선택 단어의 행이 몇 개인지 확인한다.

 

import csv
import os

def filter_and_delete_rows(csv_file, keyword):
    temp_file = csv_file.replace('.csv', '_temp.csv')
    with open(csv_file, 'r', newline='', encoding='utf-8') as read_file, \
         open(temp_file, 'w', newline='', encoding='utf-8') as write_file:
        
        reader = csv.DictReader(read_file)
        if 'title' not in reader.fieldnames:
            raise ValueError("CSV 파일에 'title' 열이 없습니다.")
        
        writer = csv.DictWriter(write_file, fieldnames=reader.fieldnames)
        writer.writeheader()
        
        seen_titles = set()
        for row in reader:
            title = row['title']
            if keyword not in title and title not in seen_titles:
                writer.writerow(row)
                seen_titles.add(title)

    os.replace(temp_file, csv_file)

# CSV 파일 경로
csv_file = 'test_coopang.csv'

# 삭제할 키워드
keyword = '3개'

# 키워드가 포함된 행 삭제
filter_and_delete_rows(csv_file, keyword)

 

그리고 삭제할 키워드가 들어가면 포함된 행을 삭제하는 함수를 제작하여 행을 정리해주었다.

하지만 여기서 문제가 발생한다. title이 있음에도 없다고 판단시켜 실행이 안되었다. 

이것을 해결하기 위해 csv 파일 열 이름 확인시킨다.

# 잘 변경되었는 지 확인 작업
import csv

def print_csv_headers(csv_file):
    with open(csv_file, 'r', newline='', encoding='utf-8') as file:
        reader = csv.reader(file)
        headers = next(reader)
        print("CSV 파일의 열 이름:", headers)

# CSV 파일 경로
csv_file = 'coopang.csv'

# CSV 파일의 열 이름 출력
print_csv_headers(csv_file)

 

출력을 시켜보니 title이 아닌 \ufefftitle로 설정이 되어있었다. 그래서 이걸 다시 변경해주었다.

## csv title의 이름이 \ufefftitle의 오류가 있어 변경시켜줌

import csv
import os

# CSV 파일의 헤더를 변경하는 함수
def change_csv_header(csv_file, old_header, new_header):
    temp_file = csv_file.replace('.csv', '_temp.csv')
    with open(csv_file, 'r', newline='', encoding='utf-8-sig') as read_file, \
         open(temp_file, 'w', newline='', encoding='utf-8') as write_file:
        
        reader = csv.reader(read_file)
        writer = csv.writer(write_file)
        
        headers = next(reader)
        headers = [new_header if header == old_header else header for header in headers]
        writer.writerow(headers)
        
        for row in reader:
            writer.writerow(row)

    os.replace(temp_file, csv_file)

# CSV 파일 경로
csv_file = 'coopang.csv'

# 변경할 열 이름
old_header = '\ufefftitle'
new_header = 'title'

# 열 이름 변경
change_csv_header(csv_file, old_header, new_header)

 

이렇게 변경한 csv파일에서 다시 키워드 들어가면 삭제하게 한다.

import pandas as pd

# CSV 파일 경로
csv_file = 'coopang.csv'

# CSV 파일을 읽어서 데이터프레임으로 변환
df = pd.read_csv(csv_file, encoding='utf-8-sig')

# 열 이름의 공백 제거
df.columns = df.columns.str.strip()

# price 열이 문자열 형식인 경우에만 공백 제거 및 숫자로 변환
if df['price'].dtype == 'object':
    df['price'] = df['price'].str.strip().replace('[\$,]', '', regex=True).astype(float)

# review_cnt 열이 문자열 형식인 경우에만 공백 제거 및 숫자로 변환
if df['review_cnt'].dtype == 'object':
    df['review_cnt'] = df['review_cnt'].str.strip().astype(int)

# 삭제할 키워드 목록
keywords = ['2개', '3개', '4개', '5개']

# 키워드가 포함된 행 삭제
pattern = '|'.join(keywords)
df = df[~df['title'].str.contains(pattern)]

# 중복된 'title' 행 제거
df.drop_duplicates(subset=['title'], keep='first', inplace=True)

# 변경된 데이터프레임을 다시 CSV 파일로 저장
df.to_csv("clean_coopang.csv", index=False, encoding='utf-8')

# 데이터프레임 출력 (선택사항)
print(df)

원하는 키워드 삭제 목록을 작성하고 삭제를 하니 1000개의 데이터가 480개로 줄어든 것을 알 수 있었다.

 

다음에는 쿠팡 csv를 가지고 시각화를 진행해 볼 것이다.

반응형

'Python > 파이썬 크롤링' 카테고리의 다른 글

쿠팡 리뷰 크롤링 뚫는 법  (0) 2024.06.07
올리브영 크롤링 하기  (1) 2024.06.02
글로우픽 크롤링  (0) 2024.05.29
[네이버 뉴스] 크롤링 하는 방법  (0) 2024.05.08