Seongwon Lim

[Python] 쿠팡 상품 정보 크롤링하고 엑셀로 저장하기 본문

Python

[Python] 쿠팡 상품 정보 크롤링하고 엑셀로 저장하기

limsw 2022. 5. 8. 16:58
반응형

서론

이번 글에서는 쿠팡 홈페이지의 상품 정보들을 크롤링하는 예제를 다뤄보고자 한다.
상품의 이름, 가격, 리뷰 수, 구매 링크 내용을 크롤링하여 엑셀 파일에 저장하는 것까지 해볼 예정이다.

 

  • 쿠팡 홈페이지를 상업적인 목적으로 크롤링하는 것은 저작권 침해로 문제가 될 수 있으므로 크롤링을 공부하는 목적으로 사용하여야 한다.

크롤링 시작하기

위처럼 필자는 쿠팡 검색어에 아이폰 키워드를 입력한 뒤 이동하는 주소에서 크롤링을 할 것이다.

 

  • 주소는 여기를 클릭하면 바로 이동할 수 있다.

 

이제 화면을 살펴보자.

검색 조건에 별다른 필터를 주지 않았을 때 이와 같은 상품 목록들이 나왔다. 한 페이지에는 4개의 상품씩 총 9줄로 구성된 것을 확인할 수 있을 것이다. 필자는 상품 정보 중에서 상품명, 가격, 리뷰 수, 구매 링크 4개의 정보를 크롤링하고자 한다.

쿠팡 홈페이지 읽어오기

import requests
from bs4 import BeautifulSoup

headers = {'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}
res = requests.get("https://www.coupang.com/np/search?component=&q=%EC%95%84%EC%9D%B4%ED%8F%B0&channel=user", headers = headers)

soup = BeautifulSoup(res.content, 'html.parser')

쿠팡은 GET 요청을 보낼 때 헤더가 없으면 데이터를 읽어올 수 없기 때문에 위 코드와 같이 메서드에 headers를 추가했다.

원하는 데이터 추출하기

이제 위에서 언급한 4개의 정보를 추출해보자.

# 상품 이름 추출하기
product_name = soup.select('div > div.name')

# 상품 가격 추출하기
product_price = soup.select('div.price-wrap > div.price > em > strong')

# 상품 리뷰 수 추출하기
product_review = soup.select('div.other-info > div > span.rating-total-count')

# 상품 구매 링크 추출하기
product_link = soup.select('a.search-product-link')

코드는 이와같이 간단하게 구현할 수 있다. 이제 select()안에 들어있는 셀렉터가 어떻게 위와 같이 정의되었는지 알아보자.

먼저 F12 혹은 화면에서 오른쪽 마우스 클릭 후 검사 탭을 누른다.

그리고 위 사진과 같이 좌측 상단에 있는 화살표 모양의 아이콘을 누른다.

그 다음 마우스를 위 사진처럼 상품 이름에 가져다대면 상품 이름의 셀렉터 구성이 어떻게 되어있는지 확인할 수 있다. 이제 상품 이름을 클릭하고 검색 창을 살펴보면

상품 이름의 셀렉터를 좀 더 자세하게 확인할 수 있다.

 

위 사진으로 보면 상품 이름의 셀렉터는 dl > dd > div > div.name로 정의될 수 있으며 필자는 간단하게 div > div.name으로 정의한 것이다.

CSS Selector 이용하는 법

코드 구조를 읽기 어려울 때에는 검사 창에서 제공하는 CSS Selector를 이용하면 쉽게 셀렉터 구조를 가져올 수 있다.

위처럼 해당 태그에서 오른쪽 마우스 클릭 후 CSS Selector를 복사한다.

 

결과는 #\36 344791784 > a > dl > dd > div > div.name으로 나왔다. 필자가 직접 확인한 구조와 비슷한 것을 확인할 수 있으며 복사된 셀렉터를 붙여 넣어도 되고 필자처럼 일부만 잘라서 사용할 수도 있다.

 

(상품 가격, 리뷰 수, 구매 링크 또한 상품명을 가져오는 방법과 동일한 방법으로 가져온 것이므로 3개에 대한 크롤링 설명은 생략했다.)

엑셀에 크롤링한 데이터 추가하기

이제 크롤링한 데이터를 엑셀 파일에 추가해보자. 여기를 클릭하면 파이썬에서 엑셀 파일을 사용하는 법을 상세하게 다루고 있으므로 참고하면 좋을 것 같다.

# 엑셀 생성 및 활성화
excel = openpyxl.Workbook()
sheet = excel.active

# 시트 제목 및 컬럼 이름 정의
sheet.title = "쿠팡 상품 정보 크롤링하기"
sheet.append(['상품명', '가격', '리뷰 수', '상품 링크'])

# 상품 정보 시트에 추가하기
for name, price, review, link in zip(product_name, product_price, product_review, product_link):
    p_name = name.text
    p_price = price.text
    p_review_cnt = re.sub("[()]","", review.text)
    p_link = "https://coupang.com" + link['href']
    
    sheet.append([p_name, p_price, p_review_cnt, p_link])

excel.save('coupang_item_list.xlsx')

필자는 현재 4개의 상품 정보를 크롤링했기 때문에 4개의 리스트 변수를 가지고 있다. 이 때에는 zip()메서드를 이용하면 for문 인자로 여러 개의 리스트를 줄 수 있다.

정규표현식을 이용하여 리뷰 수 데이터 가공하기

리뷰 개수데이터를 가공하기 전에 review.text를 출력해보면 데이터 구성이 (5100) 처럼 리뷰 개수가 괄호로 감싸져 있는 것을 확인할 수 있을 것이다. 따라서 필자는 정규표현식을 이용하여 괄호를 없애고 숫자만 저장할 수 있도록 했다.

 

import re를 통해 모듈을 불러오고 위처럼 re.sub('조건', '어떻게 바꿀 것인지', '바꿀 문자')을 정의한다.

필자는 정규표현식을 통해 바꿀 문자에 괄호가 들어있으면 괄호를 없애도록 한 것이다.

구매 링크 데이터 가공하기

구매 링크 데이터를 가공하기 전 link['href']를 출력해보면

이런 식으로 /vp/..처럼 구성되어 있다. 따라서 완성된 주소로 변경하기 위해 앞에 https://coupang.com을 붙여서 해당 상품의 주소 데이터를 가공했다. 위처럼 코드를 구성하고 실행하면 coupang_item_list.xlsx 파일이 생성된다.

엑셀 파일을 열어보면 위와 같이 시트 이름과 저장한 데이터 정보가 적절하게 들어있는 것을 확인할 수 있다.

 

그러나 상품명의 경우 이름이 긴 경우도 있고 구매 링크의 경우에는 주소만 정의되어 있고 하이퍼링크 같은 기능은 없는 상태이므로 엑셀 시트를 커스터마이징 해보기로 했다.

엑셀 시트 커스터마이징

# 컬럼 너비 조정
sheet.column_dimensions['A'].width = 60
sheet.column_dimensions['B'].width = 12
sheet.column_dimensions['C'].width = 10
sheet.column_dimensions['D'].width = 10

# 컬럼명 가운데 정렬 및 색상 정의
A1_cell = sheet['A1']
A1_cell.alignment = openpyxl.styles.Alignment(horizontal='center')
A1_cell.font = openpyxl.styles.Font(color='0055FF')

B1_cell = sheet['B1']
B1_cell.alignment = openpyxl.styles.Alignment(horizontal='center')
B1_cell.font = openpyxl.styles.Font(color='0055FF')

C1_cell = sheet['C1']
C1_cell.alignment = openpyxl.styles.Alignment(horizontal='center')
C1_cell.font = openpyxl.styles.Font(color='0055FF')

D1_cell = sheet['D1']
D1_cell.alignment = openpyxl.styles.Alignment(horizontal='center')
D1_cell.font = openpyxl.styles.Font(color='0055FF')

위 코드를 엑셀 파일 생성 코드 정의 후 아래에 붙여넣고 다시 실행해보자.

컬럼명이 가운데 정렬 및 정의한 색상을로 변경된 것을 확인할 수 있다.


이처럼 사용자가 엑셀 시트를 본인 요구 사항에 맞게 커스터마이징 할 수 있으므로 참고하면 좋을 것 같다.

구매 링크 주소 단순화하기

엑셀 시트를 보면 상품 링크 컬럼의 데이터들은 상품의 구매 링크 주소를 담고 있다. 그러나 상품 링크가 매우 긴 경우 위 사진처럼 우측으로 다른 컬럼을 침범하게 된다. 따라서 필자는 주소를 직접 시트에 넣는 것이 아니라 시트는 모두 이동하기 라는 단어로 대체하고 각 단어마다 하이퍼링크를 주어 시트를 보기 좋게 만들어보고자 한다.

먼저 엑셀 파일을 살펴보면 첫번째 상품의 구매 링크의 주소는 2행 4열에 위치한다. 상품명 이라는 위치를 (row=1, col=1)로 보면 된다.

 

따라서 열은 4로 고정이고 행은 2행부터 차례대로 1행씩 증가함을 알 수 있다. 이제 코드를 통해 살펴보자.

# 상품 정보 시트에 추가하기 - 구매 링크 단순화 기능 추가
idx = 2
for name, price, review, link in zip(product_name, product_price, product_review, product_link):
    p_name = name.text
    p_price = price.text
    p_review_cnt = re.sub("[()]","", review.text)
    p_link = "https://coupang.com" + link['href']
    
    sheet.append([p_name, p_price, p_review_cnt, '이동하기'])
    sheet.cell(row=idx, column=4).hyperlink = p_link # 하이퍼링크 추가
    
    idx += 1

특정 셀에 하이퍼링크를 추가하기 위해서는 위처럼 sheet.cell(row=, column=).hyperlink=...을 사용하면 된다.

 

필자는 초기값을 2로 가지는 idx 변수를 생성했고 row=에 해당 변수를 넣어 행의 위치를 지정했으며 반복마다 행을 한 칸씩 밑으로 이동하게끔 구현한 것이다. 이제 다시 수정한 내용을 바탕으로 코드를 실행해보자.

해당 컬럼이 모두 이동하기로 바뀐 것을 볼 수 있으며

하이퍼링크 편집 메뉴를 통해 살펴보면 하이퍼링크로 해당 상품의 구매 링크가 알맞게 들어가있는 것을 확인할 수 있다.


전체 코드

import requests
from bs4 import BeautifulSoup
import re, openpyxl

headers = {'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 11_0_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}
res = requests.get("https://www.coupang.com/np/search?component=&q=%EC%95%84%EC%9D%B4%ED%8F%B0&channel=user", headers = headers)

soup = BeautifulSoup(res.content, 'html.parser')

product_name = soup.select('div > div.name')
product_price = soup.select('div.price-wrap > div.price > em > strong')
product_review = soup.select('div.other-info > div > span.rating-total-count')
product_link = soup.select('a.search-product-link')

excel = openpyxl.Workbook()
sheet = excel.active

sheet.title = "쿠팡 상품 정보 크롤링하기"
sheet.append(['상품명', '가격', '리뷰 수', '상품 링크'])

sheet.column_dimensions['A'].width = 60
sheet.column_dimensions['B'].width = 12
sheet.column_dimensions['C'].width = 10
sheet.column_dimensions['D'].width = 10

A1_cell = sheet['A1']
A1_cell.alignment = openpyxl.styles.Alignment(horizontal='center')
A1_cell.font = openpyxl.styles.Font(color='0055FF')

B1_cell = sheet['B1']
B1_cell.alignment = openpyxl.styles.Alignment(horizontal='center')
B1_cell.font = openpyxl.styles.Font(color='0055FF')

C1_cell = sheet['C1']
C1_cell.alignment = openpyxl.styles.Alignment(horizontal='center')
C1_cell.font = openpyxl.styles.Font(color='0055FF')

D1_cell = sheet['D1']
D1_cell.alignment = openpyxl.styles.Alignment(horizontal='center')
D1_cell.font = openpyxl.styles.Font(color='0055FF')

idx = 2
for name, price, review, link in zip(product_name, product_price, product_review, product_link):
    p_name = name.text
    p_price = price.text
    p_review_cnt = re.sub("[()]","", review.text)
    p_link = "https://coupang.com" + link['href']
    
    sheet.append([p_name, p_price, p_review_cnt, '이동하기'])
    sheet.cell(row=idx, column=4).hyperlink = p_link
    
    idx += 1

excel.save('coupang_item_list.xlsx')
Comments