본문 바로가기
Database

MySQL - 실전 크롤링과 데이터베이스

by DGK 2021. 11. 11.

 

데이터베이스 입문 수업을 듣고 중요한 내용을 정리했습니다.
개인 공부 후 자료를 남기기 위한 목적이므로 내용 상에 오류가 있을 수 있습니다.

 

실전 크롤링과 데이터베이스(MySQL)

실전 크롤링으로 추출한 데이터를 데이터베이스 스키마(Schema)에 저장하는 연습을 하고자 한다.

 

스키마(Schema) 설계

CREATE DATABASE bestproducts DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 

USE bestproducts

 

```

결과 :

```

 

우선, Workbench로 bestproducts 라는 데이터베이스를 만들고 해당 데이터베이스를 사용할 준비를 한다.

참고로, DEFAULT CHARSET=utf8 COLLATE=utf8_bin; 코드는 한글 처리에 문제가 있을 경우를 대비하여 옵션으로

추가한 SQL 코드이다.

 

 

import pymysql
db = pymysql.connect(host='localhost', port=3306, user='root', passwd='mysql pw', db='bestproducts', charset='utf8')
cursor = db.cursor()

sql = '''
CREATE TABLE items (
    item_code VARCHAR(20) NOT NULL PRIMARY KEY,
    title VARCHAR(200) NOT NULL,
    ori_price INT NOT NULL,
    dis_price INT NOT NULL,
    discount_percent INT NOT NULL,
    provider VARCHAR(100)
);
'''
cursor.execute(sql)

sql = '''
CREATE TABLE ranking (
    num INT AUTO_INCREMENT NOT NULL PRIMARY KEY,
    main_category VARCHAR(50) NOT NULL,
    sub_category VARCHAR(50) NOT NULL,
    item_ranking TINYINT UNSIGNED NOT NULL,
    item_code VARCHAR(10) NOT NULL,
    FOREIGN KEY(item_code) REFERENCES items(item_code)
);
'''
cursor.execute(sql)

db.commit()
db.close()

 

```

결과 :

items TABLE
ranking TABLE

```

 

위의 예시코드는 pymysql 라이브러리를 사용해서, 두 개의 테이블을 만든 것이다. 

참고로, Foreign Key가 없는 테이블을 먼저 생성하고 이후에 Foreign Key를 가진 테이블을 생성해야만 에러가 발생

하지 않는다.

 

스키마(Schema)를 설계하는 것의 의미는 데이터를 저장할 테이블을 분리하고, Foreign Key와 Primary Key를 

사용하여 테이블 간의 관계를 설정하는 것이다.

 

 

스키마(Schema)에 저장할 데이터를 크롤링하기

G마켓 베스트 main category 데이터 추출

 

import requests
from bs4 import BeautifulSoup

res = requests.get('http://corners.gmarket.co.kr/Bestsellers')
soup = BeautifulSoup(res.content, 'html.parser')

categories = soup.select('div.gbest-cate ul.by-group li a')
for category in categories:
    print('http://corners.gmarket.co.kr/' + category['href'], category.get_text())

 

```

결과 :

http://corners.gmarket.co.kr//Bestsellers ALL
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01 패션의류
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02 신발/잡화
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G03 화장품/헤어
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G04 유아동/출산
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G07 식품
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G08 생활/주방/건강
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G09 가구/침구
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G05 스포츠/자동차
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G06 컴퓨터/전자
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G11 여행
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓

 

```

 

G마켓의 Best 페이지에서 메인 카테고리명의 정보를 크롤링으로 가져온 결과이다.

 

 

import requests
from bs4 import BeautifulSoup

res = requests.get('http://corners.gmarket.co.kr/Bestsellers')
soup = BeautifulSoup(res.content, 'html.parser')

categories = soup.select('div.gbest-cate ul.by-group li a')
for category in categories:
    get_category('http://corners.gmarket.co.kr/' + category['href'], category.get_text())
    
    
def get_category(category_link, category_name):
    print(category_link, category_name)
    res = requests.get(category_link)
    soup = BeautifulSoup(res.content, 'html.parser')
    
    sub_categories = soup.select('div.navi.group ul li a')
    for sub_category in sub_categories:
        print(category_link, category_name, sub_category.get_text(), 'http://corners.gmarket.co.kr/' + sub_category['href'])

 

```

결과 :

http://corners.gmarket.co.kr//Bestsellers ALL
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01 패션의류
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01 패션의류 브랜드 여성의류 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01&subGroupCode=S161
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01 패션의류 브랜드 남성의류 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01&subGroupCode=S162
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01 패션의류 브랜드 진/캐쥬얼  http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01&subGroupCode=S163
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01 패션의류 여성의류 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01&subGroupCode=S102
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01 패션의류 남성의류 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01&subGroupCode=S002
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01 패션의류 언더웨어 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01&subGroupCode=S088
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02 신발/잡화
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02 신발/잡화 브랜드 신발/가방 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02&subGroupCode=S166
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02 신발/잡화 브랜드 쥬얼리/시계 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02&subGroupCode=S167
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02 신발/잡화 여성신발 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02&subGroupCode=S004
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02 신발/잡화 남성신발 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02&subGroupCode=S005
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02 신발/잡화 운동화 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02&subGroupCode=S007
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02 신발/잡화 가방/지갑 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02&subGroupCode=S008
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02 신발/잡화 잡화/액세서리 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02&subGroupCode=S127
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02 신발/잡화 수입명품 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02&subGroupCode=S134
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02 신발/잡화 여행가방 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G02&subGroupCode=S172

 

...


http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반 시/소설 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10&subGroupCode=S044
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반 경제/경영/개발 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10&subGroupCode=S093
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반 인문/사회/과학/IT http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10&subGroupCode=S094
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반 가정/생활/취미/레저 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10&subGroupCode=S095
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반 만화/잡지 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10&subGroupCode=S096
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반 해외원서 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10&subGroupCode=S097
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반 학습/수험 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10&subGroupCode=S045
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반 어린이 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10&subGroupCode=S073
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반 음반 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10&subGroupCode=S046
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10 도서/음반 DVD http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G10&subGroupCode=S074
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G11 여행
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G11 여행 국내여행 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G11&subGroupCode=S047
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G11 여행 해외여행 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G11&subGroupCode=S048
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G11 여행 여행소품 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G11&subGroupCode=S049
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G11 여행 G9 해외패키지 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G11&subGroupCode=S181
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓 외식 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12&subGroupCode=S051
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓 온라인컨텐츠 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12&subGroupCode=S052
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓 생활쿠폰 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12&subGroupCode=S053
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓 상품권 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12&subGroupCode=S148
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓 모바일 상품권 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12&subGroupCode=S135

 

```

 

G마켓의 Best 페이지에서 메인/서브 카테고리명의 정보를 크롤링으로 가져온 결과이다.

 

 

import requests
from bs4 import BeautifulSoup

res = requests.get('http://corners.gmarket.co.kr/Bestsellers')
soup = BeautifulSoup(res.content, 'html.parser')

categories = soup.select('div.gbest-cate ul.by-group li a')
for category in categories:
    get_category('http://corners.gmarket.co.kr/' + category['href'], category.get_text())
    
    
def get_category(category_link, category_name):
    print(category_link, category_name)
    res = requests.get(category_link)
    soup = BeautifulSoup(res.content, 'html.parser')
    
    get_item(soup, category_name, 'ALL')
    
    sub_categories = soup.select('div.navi.group ul li a')
    for sub_category in sub_categories:
        print(category_link, category_name, sub_category.get_text(), 'http://corners.gmarket.co.kr/' + sub_category['href'])
       
       
def get_item(html, category_name, sub_category_name):
    best_item = html.select('div.best-list')
    for index, item in enumerate(best_item[1].select('li')):
        ranking = index + 1
        title = item.select_one('a.itemname')
        ori_price = item.select_one('div.o-price')
        dis_price = item.select_one('div.s-price strong span')
        discount_percent = item.select_one('div.s-price em')
        
        if ori_price == None or ori_price.get_text() == '':
            ori_price = dis_price
        
        ori_price = ori_price.get_text().replace(',', '').replace('원', '')
        dis_price = dis_price.get_text().replace(',', '').replace('원', '')
        
        if discount_percent == None or discount_percent.get_text() == '':
            discount_percent = 0
        else:
            discount_percent = discount_percent.get_text().replace('%', '')
        
        print(category_name, sub_category_name, ranking, title.get_text(), ori_price, dis_price, discount_percent)

 

```

결과 :

http://corners.gmarket.co.kr//Bestsellers ALL
ALL ALL 1 [다이슨](스마일캐시7만)본사 무선청소기 V10 플러피 오리진 480000 480000 0
ALL ALL 2 [안흥찐빵]원조 안흥 할매 쌀 찐빵 / 30개 / 무료배송 22000 9900 55
ALL ALL 3 한복선 버섯 뚝배기 불고기 400gX6팩 18900 17010 10
ALL ALL 4 (Jewel Case Ver. SET) MONSTA X Mini Album - NO LIMIT (몬스타엑스 미니10집 5종 세트) 55000 55000 0
ALL ALL 5 [바른]바른 곡물효소 발효효소 식이섬유 유산균 3박스/총90포 27900 27900 0
ALL ALL 6 [유한킴벌리]크리넥스3겹 울트라클린27MX30롤X2팩 33000 33000 0
ALL ALL 7 [래핑차일드]래핑차일드PLAY_Z 스웨트팬츠 (81W79-402-01) 29900 14950 50
ALL ALL 8 [광동]비타500 젤리 x 20팩/간식/비타민c 13600 10900 19
ALL ALL 9 모노시크/20%/기모티셔츠/맨투맨/가디건/니트/바지 19700 7900 59
ALL ALL 10 [젤리스푼]아동복/아동의류/키즈경량패딩/레깅스/원피스/뽀글이 33000 9900 70
ALL ALL 11 절임배추 20kg 9포기내외 강원도 영월 고랭지 배추 35900 35550 0
ALL ALL 12 Ditty Bird 음악과 소리로 즐기며 배우는 영어사운드북 14종 선택구매 18000 9000 50
ALL ALL 13 [이지바이](20%쿠폰)놓쳐서는 안될 겨울아웃도어/아우터/티/바지 26300 7900 69
ALL ALL 14 씨투엠 수학 교구상자 펜토미노턴/큐브빌드 선택구매(워크북포함)(NEW) 65000 43500 33
ALL ALL 15 [블랙야크키즈](신세계하남점)[블랙야크키즈] 한겨울   롱패딩 2종1택 [정상가 338000원 모듈다운자켓L 피어L다운자켓] 99000 75240 24
ALL ALL 16 쿠폰20% 맨투맨/원피스/블라우스/스커트/기모바지 33300 10000 69
ALL ALL 17 [그린몬스터]디톡 콤부차 레몬홍차 6박스+보틀 증정 / 20억 유산균 24000 19900 17
ALL ALL 18 (Jewel Case Ver. SET/Ver SET) MONSTA X Mini Album - NO LIMIT (몬스타엑스 미니10집 9종 세트) 120200 120200 0
ALL ALL 19 다이아몬드 후라이팬 1+1 (팬28/궁중28) +사은품 39900 39900 0
ALL ALL 20 [닥터그루트]닥터그루트 탈모완화샴푸 빅스마일데이 패키지 87000 48000 44
ALL ALL 21 남녀공용 오리털 파카 덕다운 후드 숏패딩 겨울패딩 27800 23330 16
ALL ALL 22 [컬럼비아][컬럼비아] 남여 플리스 자켓 C24-WE3220 40500 29970 26
ALL ALL 23 [피죤]섬유유연제 3100ml x3개 핑크+피죤1L/하루특가7500원 23800 11900 50
ALL ALL 24 [락토핏]20+15% 종근당건강 락토핏 5X 생유산균 골드 5통 250P 70900 66900 5
ALL ALL 25 브리치x럭키567 20%+10%쿠폰 맨투맨/패딩/니트 46300 13900 69
ALL ALL 26 [세타필]세타필 대용량1+1(로션 473ml+로션 473ml) +미니5종 39000 24900 36
ALL ALL 27 3+1 빅사이즈 겨울 남여 안감 융털바지/기모트레이닝 26300 7900 69
ALL ALL 28 [Gfresh]해가득 뚝불고기 400g5봉/10인분(전복해물만두1봉증정) 33200 14900 55
ALL ALL 29 [래핑차일드]래핑차일드PLAY_Z 스웨트셔츠 (81W79-332-01) 29900 14950 50
ALL ALL 30 시스터 20%쿠폰 기모추가 빅사이즈/롱원피스/세트 24800 9900 60
ALL ALL 31 [베베앙]베베앙 아기물티슈  시그니처 대용량 100매 캡형 10팩 25800 12900 50
ALL ALL 32 크리스마스 워터볼 LED 오르골 스노우볼 눈사람 소형 17500 16500 5
ALL ALL 33 [아몬드브리즈]아몬드브리즈 오리지널 190ML 48팩 30900 26900 12
ALL ALL 34 20%쿠폰 겨울신상 루즈핏 뽀글이 니트 코트 기모티 28600 10900 61
ALL ALL 35 [Gfresh]프레시지 골든라벨 스테이크 2인분 11900 11790 0
ALL ALL 36 [BYC]20%쿠폰/여성팬티/노라인/위생/보정/면/엉뽕/최다모음 17250 6900 60
ALL ALL 37 [울트라PC]LG울트라PC 15UD40N-GX36K 최종56만 가성비1위 인기 788420 749000 4
ALL ALL 38 [팬콧키즈]20%+10% 무료반품 쿠폰 팬콧 주니어 윈터 아우터 59600 17900 69
ALL ALL 39 영어를 배우는 초등학생을 위한 재밌고 가르치기쉬운/3rd Edition Super Kids/수퍼키즈/번역본제공 62800 39800 36
ALL ALL 40 엄마옷로즈맘 겨울신상 5060중년여성의류 43000 12900 70
ALL ALL 41 (한정반/예약특전) 스트레이 키즈 (Stray Kids) - Holiday Special Single Christmas EveL 13400 13400 0
ALL ALL 42 제주 달콤 조생 타이벡 감귤 10kg 로얄과(S~M)농할20% 16900 16740 0
ALL ALL 43 [미니케이]국산 30%할인 발열유아 아동 주니어 내의/실내복/잠옷 26300 7900 69
ALL ALL 44 [진라면]진라면 매운맛 40봉 24500 24500 0
ALL ALL 45 [구글플레이](Google Play 기프트코드) 10만원 / 구글 기프트카드 100000 93000 7
ALL ALL 46 [할리스]리얼 벨지안 초코라떼30T /최종혜택가 10930원 32700 14700 55
ALL ALL 47 [다우니]초고농축 다우니 섬유유연제 엑스퍼트 실내건조 1L 3개 21450 16500 23
ALL ALL 48 [블루독베이비]블루독베이비ACORN 맨투맨 (40C14-334-08) 65000 32500 50
ALL ALL 49 [밍크뮤]밍크뮤MUI플라워 맨투맨  (30C15-334-06) 69000 34500 50
ALL ALL 50 [프로쉬]독일 프로쉬 식기세척기세제 30개입 3세트+주방100ml 65800 32900 50

...


e쿠폰/티켓 ALL 51 [투썸플레이스](투썸플레이스) 스트로베리 초콜릿 생크림 35000 33600 4
e쿠폰/티켓 ALL 52 [넥슨](카드가능)(넥슨)(PIN발송) 온라인게임상품권 5만원 50000 47100 5
e쿠폰/티켓 ALL 53 [스타벅스](스타벅스)(APP전용) e카드 5만원 교환권 50000 50000 0
e쿠폰/티켓 ALL 54 카카오키즈 프리미엄 교육 1년 무제한 통합이용권 (이용권 카드+가이드북) 249000 139000 44
e쿠폰/티켓 ALL 55 [CU](CU) 모바일금액권 1만원/ 실시간발송 10000 9700 3
e쿠폰/티켓 ALL 56 카카오키즈 프리미엄 교육 1년 통합 이용권 패키지 (이용권 카드+가이드북+자석교구 3종 포함) 324000 159000 50
e쿠폰/티켓 ALL 57 [쿠우쿠우](쿠우쿠우) 기프티카드 7만원권 70000 67900 3
e쿠폰/티켓 ALL 58 [로제타스톤]뉴 로제타스톤 (1번 구매로) 24개 언어 무제한 평생 학습권 79% 할인 699000 230000 67
e쿠폰/티켓 ALL 59 [스타벅스](스타벅스) Happy Birthday Set 15100 15100 0
e쿠폰/티켓 ALL 60 [도서문화상품권](북앤라이프) 도서문화상품권 오만원권 50000 47000 6
e쿠폰/티켓 ALL 61 [컬쳐랜드문화상품권](카드가능)(컬쳐랜드) 온라인문화상품권 5천원권 5000 5000 0
e쿠폰/티켓 ALL 62 카카오키즈 프리미엄 교육 1년 무제한 홈스쿨이용권 (이용권 카드+가이드북) 133800 79000 40
e쿠폰/티켓 ALL 63 [쿠우쿠우](쿠우쿠우) 기프티카드 10만원권 100000 97000 3
e쿠폰/티켓 ALL 64 [파리바게뜨](파리바게뜨) 마이넘버원3 27000 27000 0
e쿠폰/티켓 ALL 65 [윌라]윌라 오디오북+클래스 무제한 멤버십 12개월권 118800 89000 25
e쿠폰/티켓 ALL 66 재팬머니 - 일본 아이튠즈 카드 10000엔 (앱스토어OK) 101000 101000 0
e쿠폰/티켓 ALL 67 [GS25]GS25 모바일 3만원권 30000 29100 3
e쿠폰/티켓 ALL 68 [엔타스]엔타스상품권 10만원권(경복궁/삿뽀로/고구려/면세점) 91000 91000 0
e쿠폰/티켓 ALL 69 (SK텔레콤) T데이터쿠폰 2GB 19000 13680 28
e쿠폰/티켓 ALL 70 크래버대게나라 상품권 5만원권 /10만원권 (대게나라) 78000 78000 0
e쿠폰/티켓 ALL 71 [아웃백스테이크하우스]아웃백 디지털 5만원권 50000 46950 6
e쿠폰/티켓 ALL 72 [GS수퍼마켓](GS THE FRESH)금액상품권3만원 30000 29100 3
e쿠폰/티켓 ALL 73 [맥도날드]맥도날드 디지털 2만원권 20000 20000 0
e쿠폰/티켓 ALL 74 [쿠우쿠우](쿠우쿠우) 기프티카드 3만원권 30000 29100 3
e쿠폰/티켓 ALL 75 [롯데상품권]신용카드/현대/롯데/신세계백화점상품권/5만원 49000 49000 0
e쿠폰/티켓 ALL 76 [BBQ](BBQ) 황금올리브치킨+콜라 1.25L 20000 19200 4
e쿠폰/티켓 ALL 77 [투썸플레이스]투썸플레이스 5만원권 50000 47500 5
e쿠폰/티켓 ALL 78 [스타벅스](스타벅스) 카페아메리카노 Tall 4100 4100 0
e쿠폰/티켓 ALL 79 [파리바게뜨](파리바게뜨)(수능) 모바일 3만원권 30000 30000 0
e쿠폰/티켓 ALL 80 [GS25]GS25 모바일 2만원권 20000 19400 3
e쿠폰/티켓 ALL 81 [코스트코]코스트코상품권 10만원권/회원대용/배송비 1번만 부과 100650 100650 0
e쿠폰/티켓 ALL 82 [도서문화상품권](북앤라이프) 도서문화상품권 이만원권 20000 18800 6
e쿠폰/티켓 ALL 83 [BHC](BHC) 뿌링클+치즈볼+콜라1.25L 24000 23040 4
e쿠폰/티켓 ALL 84 [금강제화]신용카드/금강제화 상품권10만원/랜드로바/구두티켓 74600 74600 0
e쿠폰/티켓 ALL 85 GS25 / CU / 세븐일레븐 모바일 편의점상품권 1만원권 9700 9700 0
e쿠폰/티켓 ALL 86 [에그드랍](빅스마일데이)(에그드랍) 1만원권 10000 9000 10
e쿠폰/티켓 ALL 87 [스타벅스](스타벅스) 너만큼 완벽한 디저트 세트 20300 20300 0
e쿠폰/티켓 ALL 88 [도서문화상품권](북앤라이프) 도서문화상품권 일만원권 10000 9400 6
e쿠폰/티켓 ALL 89 (폴바셋) 아이스크림 카페라떼(Standard) 6300 5350 15
e쿠폰/티켓 ALL 90 [아웃백스테이크하우스]아웃백 디지털 3만원권 30000 28170 6
e쿠폰/티켓 ALL 91 [배스킨라빈스](배스킨라빈스) 듀얼와츄원 NO.9 30000 30000 0
e쿠폰/티켓 ALL 92 [LF몰]LF몰 디지털 금액권 5만원권 50000 46000 8
e쿠폰/티켓 ALL 93 2022 펭수 시즌그리팅 세트  펭수 시즌그리팅 42000 42000 0
e쿠폰/티켓 ALL 94 [호두잉글리시]호두잉글리시 PC 평생패키지 598000 299000 50
e쿠폰/티켓 ALL 95 [엔타스]엔타스상품권 10만원(경복궁/삿뽀로/고구려 등) 92000 92000 0
e쿠폰/티켓 ALL 96 [BHC](BHC) 기프티카드 3만원권 30000 28800 4
e쿠폰/티켓 ALL 97 [맥도날드]맥도날드 디지털 1만원권 10000 10000 0
e쿠폰/티켓 ALL 98 [올리브영](올리브영) 기프트카드 5만원권 50000 50000 0
e쿠폰/티켓 ALL 99 카카오키즈 프리미엄 교육 1년 홈스쿨 이용권 패키지 (이용권 카드+가이드북+자석교구 한글 포함) 158800 85000 46
e쿠폰/티켓 ALL 100 [파리바게뜨](파리바게뜨) 고구마케이크 25000 25000 0
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓 외식 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12&subGroupCode=S051
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓 온라인컨텐츠 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12&subGroupCode=S052
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓 생활쿠폰 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12&subGroupCode=S053
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓 상품권 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12&subGroupCode=S148
http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12 e쿠폰/티켓 모바일 상품권 http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G12&subGroupCode=S135

 

```

 

G마켓의 Best 페이지에서 메인/서브 카테고리명, 메인 카테고리의 상품 정보를 크롤링으로 가져온 결과이다.

 

참고로, get_category() 함수 안의 get_items(soup, category_name, "ALL") 코드에서 첫 번째 인자가 soup인

이유는 이미 변수 soup 안에 메인 카테고리의 웹 페이지가 분석(파싱)되어 들어가있기 때문이다.

즉, 해당 분석 내용(변수 soup에 들어있는 파싱 내용)을 바탕으로 메인 카테고리의 상품정보를 크롤링하기 위함이다.

 

 

import requests
from bs4 import BeautifulSoup

res = requests.get('http://corners.gmarket.co.kr/Bestsellers')
soup = BeautifulSoup(res.content, 'html.parser')

categories = soup.select('div.gbest-cate ul.by-group li a')
for category in categories:
    get_category('http://corners.gmarket.co.kr/' + category['href'], category.get_text())
    

def get_category(category_link, category_name):
    print(category_link, category_name)
    res = requests.get(category_link)
    soup = BeautifulSoup(res.content, 'html.parser')
    
    get_item(soup, category_name, 'ALL')
    
    sub_categories = soup.select('div.navi.group ul li > a')
    for sub_category in sub_categories:
        res = requests.get('http://corners.gmarket.co.kr/' + sub_category['href'])
        soup = BeautifulSoup(res.content, 'html.parser')
        get_item(soup, category_name, sub_category.get_text())
    

def get_item(html, category_name, sub_category_name):
    best_item = html.select('div.best-list')
    for index, item in enumerate(best_item[1].select('li')):
        ranking = index + 1
        title = item.select_one('a.itemname')
        ori_price = item.select_one('div.o-price')
        dis_price = item.select_one('div.s-price strong span')
        discount_percent = item.select_one('div.s-price em')
        
        if ori_price == None or ori_price.get_text() == '':
            ori_price = dis_price
        
        if dis_price == None:
            ori_price, dis_price = 0, 0
        else:
            ori_price = ori_price.get_text().replace(',', '').replace('원', '')
            dis_price = dis_price.get_text().replace(',', '').replace('원', '')
        
        if discount_percent == None or discount_percent.get_text() == '':
            discount_percent = 0
        else:
            discount_percent = discount_percent.get_text().replace('%', '')
        
        print(category_name, sub_category_name, ranking, title.get_text(), ori_price, dis_price, discount_percent)

 

```

결과 :

http://corners.gmarket.co.kr//Bestsellers ALL
ALL ALL 1 [다이슨](스마일캐시7만)본사 무선청소기 V10 플러피 오리진 480000 480000 0
ALL ALL 2 [안흥찐빵]원조 안흥 할매 쌀 찐빵 / 30개 / 무료배송 22000 9900 55
ALL ALL 3 한복선 버섯 뚝배기 불고기 400gX6팩 18900 17010 10
ALL ALL 4 (Jewel Case Ver. SET) MONSTA X Mini Album - NO LIMIT (몬스타엑스 미니10집 5종 세트) 55000 55000 0
ALL ALL 5 [바른]바른 곡물효소 발효효소 식이섬유 유산균 3박스/총90포 27900 27900 0
ALL ALL 6 [유한킴벌리]크리넥스3겹 울트라클린27MX30롤X2팩 33000 33000 0
ALL ALL 7 [래핑차일드]래핑차일드PLAY_Z 스웨트팬츠 (81W79-402-01) 29900 14950 50
ALL ALL 8 [광동]비타500 젤리 x 20팩/간식/비타민c 13600 10900 19
ALL ALL 9 모노시크/20%/기모티셔츠/맨투맨/가디건/니트/바지 19700 7900 59
ALL ALL 10 [젤리스푼]아동복/아동의류/키즈경량패딩/레깅스/원피스/뽀글이 33000 9900 70
ALL ALL 11 절임배추 20kg 9포기내외 강원도 영월 고랭지 배추 35900 35550 0
ALL ALL 12 Ditty Bird 음악과 소리로 즐기며 배우는 영어사운드북 14종 선택구매 18000 9000 50
ALL ALL 13 [이지바이](20%쿠폰)놓쳐서는 안될 겨울아웃도어/아우터/티/바지 26300 7900 69
ALL ALL 14 씨투엠 수학 교구상자 펜토미노턴/큐브빌드 선택구매(워크북포함)(NEW) 65000 43500 33
ALL ALL 15 [블랙야크키즈](신세계하남점)[블랙야크키즈] 한겨울   롱패딩 2종1택 [정상가 338000원 모듈다운자켓L 피어L다운자켓] 99000 75240 24
ALL ALL 16 쿠폰20% 맨투맨/원피스/블라우스/스커트/기모바지 33300 10000 69
ALL ALL 17 [그린몬스터]디톡 콤부차 레몬홍차 6박스+보틀 증정 / 20억 유산균 24000 19900 17
ALL ALL 18 (Jewel Case Ver. SET/Ver SET) MONSTA X Mini Album - NO LIMIT (몬스타엑스 미니10집 9종 세트) 120200 120200 0
ALL ALL 19 다이아몬드 후라이팬 1+1 (팬28/궁중28) +사은품 39900 39900 0
ALL ALL 20 [닥터그루트]닥터그루트 탈모완화샴푸 빅스마일데이 패키지 87000 48000 44

 

...


http://corners.gmarket.co.kr//Bestsellers?viewType=G&groupCode=G01 패션의류
패션의류 ALL 1 [게스]20%+10%게스 신상 수지 패딩 외 공용겨울BEST 130000 39000 70
패션의류 ALL 2 브리치x럭키567 20%+10%쿠폰 맨투맨/패딩/니트 46300 13900 69
패션의류 ALL 3 [지오다노]20+10% 지오다노신상 패딩/경량/맨투맨/팬츠/코트~76% 163000 49000 69
패션의류 ALL 4 20%쿠폰 홈쇼핑 FW 신상 코트/패딩/니트/팬츠 外 66300 19900 69
패션의류 ALL 5 요즘에/겨울신상+20%/기모/슬랙스/청바지/면팬츠/3XL~ 33000 9900 70
패션의류 ALL 6 브리치x허니제이 20%+10%쿠폰 니트/맨투맨/패딩 63000 18900 70
패션의류 ALL 7 20%쿠폰 수맘 따뜻한 수면 잠옷 원피스 홈웨어 세트 27200 10900 59
패션의류 ALL 8 브리치x조아맘 20%+10%쿠폰 경량패딩/니트/후드집업 83000 24900 70
패션의류 ALL 9 [자주]자주 빅스에 놓치면 아쉬운 찐템모음 패션 BEST50 69900 35900 48
패션의류 ALL 10 에이블린20%/겨울신상/기모맨투맨/가디건/니트/원피스 32300 12900 60
패션의류 ALL 11 쿠폰20% 맨투맨/원피스/블라우스/스커트/기모바지 33300 10000 69
패션의류 ALL 12 브리치X씨샵인더룸 20%+10%쿠폰 투피스/니트/맨투맨 93000 27900 70
패션의류 ALL 13 남녀공용 오리털 파카 덕다운 후드 숏패딩 겨울패딩 27800 23330 16
패션의류 ALL 14 1+1핫팩바지/기모레깅스/수면/고탄력스타킹/타이즈 23000 6900 70
패션의류 ALL 15 [지오다노]20%+7%지오다노 신상 맨투맨/기모 조거/플리스~71% 63000 19000 69
패션의류 ALL 16 시크폭스 20%쿠폰/가을신상/티셔츠/팬츠/기모 46000 14900 67
패션의류 ALL 17 [플레이텍스]플레이텍스 기간한정 브라1+1 초특가 80000 24000 70
패션의류 ALL 18 브리치x아이미마인 20%+10%쿠폰 셔츠/원피스/가디건/패딩 76300 22900 69
패션의류 ALL 19 20% 티메이 가을신상 니트 원피스 가디건  점퍼 코트 32200 12900 59
패션의류 ALL 20 패션라인20%쿠폰 신상 니트/가디건/자켓/코트/아우터 43000 12900 70

 

...


패션의류 브랜드 여성의류 1 [에잇세컨즈]쿠폰20% 지금 입기 딱 좋은 겨울상품 패딩/니트外 129000 39900 69
패션의류 브랜드 여성의류 2 [랩]LAP F/W 신상 아우터/맨투맨/가디건/니트 外 148300 46000 68
패션의류 브랜드 여성의류 3 [자주]JAJU 자주 따뜻한 겨울나기 베스트/다운 최대 60%OFF 99900 40700 59
패션의류 브랜드 여성의류 4 [에잇세컨즈]최대20%쿠폰 남녀 아울렛 상품 패딩/가디건/니트外 76000 23900 68
패션의류 브랜드 여성의류 5 [반에이크][모다아울렛]반에이크 백화점동일상품 맨투맨/니트 외 FW특가전 25000 22250 11
패션의류 브랜드 여성의류 6 [랩]LAP 신상 BEST템 빅스 파격가 코트/패딩/니트~86% 144000 72000 50
패션의류 브랜드 여성의류 7 [자주]자주 FW데일리패션 최대70%OFF 티셔츠/팬츠 外 49900 18500 62
패션의류 브랜드 여성의류 8 [브루넬리] [BRUNELLI] 터틀넥 워셔블 니트 4종 39900 39900 0
패션의류 브랜드 여성의류 9 [꼼빠니아]20+5%쿠폰 조이너스 겨울아우터 가격다운 최대특가전 156300 46900 69
패션의류 브랜드 여성의류 10 지스튜디오 21FW 소프트 몰스킨팬츠 3종 89900 80020 10
패션의류 브랜드 여성의류 11 (라인어디션) (대전신세계)포인트 와이드 슬랙스NWSLKK6300 52000 39520 24
패션의류 브랜드 여성의류 12 [플라스틱아일랜드]플라스틱아일랜드 F/W 니트/가디건/원피스 外 190300 59000 68
패션의류 브랜드 여성의류 13 C. 모데나 울라이크 원마일 팬츠 9900 9900 0
패션의류 브랜드 여성의류 14 [SOUP]25%쿠폰 겨울 신상 아우터/백화점 동일 상품 166300 49900 69
패션의류 브랜드 여성의류 15 [쉬즈미스]쉬즈미스/리스트본사시즌오프+시즌오프 최대 85%+무배 98000 49000 50
패션의류 브랜드 여성의류 16 [레코브](광주신세계)호피믹스패턴베스트(LW31AYKV903X) 35000 28860 17
패션의류 브랜드 여성의류 17 [랭앤루] 소프트 코듀로이 와이드 팬츠 3종 49900 49900 0
패션의류 브랜드 여성의류 18 (20+5%쿠폰)이사베이/씨 겨울 데일리 아우터/이너템 115900 35900 69
패션의류 브랜드 여성의류 19 [크로커다일레이디]20% 쿠폰 크로커다일레이디외 겨울인기 신상 100종 107400 53700 50
패션의류 브랜드 여성의류 20 [크로커다일레이디]20%쿠폰 크로커다일레이디 1만원대부터~아우터모음 128400 64200 50

(이하 생략)

```

 

G마켓의 Best 페이지에서 메인/서브 카테고리명, 메인/서브 카테고리의 상품 정보를 모두 크롤링으로 가져온 결과이다.

 

 

import requests
from bs4 import BeautifulSoup

res = requests.get('http://corners.gmarket.co.kr/Bestsellers')
soup = BeautifulSoup(res.content, 'html.parser')

categories = soup.select('div.gbest-cate ul.by-group li a')
for category in categories:
    get_category('http://corners.gmarket.co.kr/' + category['href'], category.get_text())
    
    
def get_category(category_link, category_name):
    print(category_link, category_name)
    res = requests.get(category_link)
    soup = BeautifulSoup(res.content, 'html.parser')
    
    get_item(soup, category_name, 'ALL')
    
    sub_categories = soup.select('div.navi.group ul li > a')
    for sub_category in sub_categories:
        res = requests.get('http://corners.gmarket.co.kr/' + sub_category['href'])
        soup = BeautifulSoup(res.content, 'html.parser')
        get_item(soup, category_name, sub_category.get_text())
    

def get_item(html, category_name, sub_category_name):
    best_item = html.select('div.best-list')
    for index, item in enumerate(best_item[1].select('li')):
        ranking = index + 1
        title = item.select_one('a.itemname')
        ori_price = item.select_one('div.o-price')
        dis_price = item.select_one('div.s-price strong span')
        discount_percent = item.select_one('div.s-price em')
        
        if ori_price == None or ori_price.get_text() == '':
            ori_price = dis_price
        
        if dis_price == None:
            ori_price, dis_price = 0, 0
        else:
            ori_price = ori_price.get_text().replace(',', '').replace('원', '')
            dis_price = dis_price.get_text().replace(',', '').replace('원', '')
        
        if discount_percent == None or discount_percent.get_text() == '':
            discount_percent = 0
        else:
            discount_percent = discount_percent.get_text().replace('%', '')
        
        product_link = item.select_one('div.thumb > a')
        item_code = product_link.attrs['href'].split('=')[1].split('&')[0]
        
        res = requests.get(product_link.attrs['href'])
        soup = BeautifulSoup(res.content, 'html.parser')
        provider = soup.select_one('div.item-topinfo_headline > p > span > a')
        if provider == None:
            provider = ''
        else:
            provider = provider.get_text()
        
        print(category_name, sub_category_name, ranking, item_code, provider, title.get_text(), ori_price, dis_price, discount_percent)

 

```

결과 :

http://corners.gmarket.co.kr//Bestsellers ALL
ALL ALL 1 2267281313 신세계백화점 [크록스](신세계강남점)[크록스] 털클로그  4종 균일가 택1 [205969] 060  11H  22Z  50P 49900 39700 20
ALL ALL 2 197096950 좋은아침 [안흥찐빵]원조 안흥 할매 쌀 찐빵 / 30개 / 무료배송 22000 9900 55
ALL ALL 3 2007833170 NS홈쇼핑 한복선 버섯 뚝배기 불고기 400gX6팩 18900 17010 10
ALL ALL 4 2051254485 스마일배송 [바른]바른 곡물효소 발효효소 식이섬유 유산균 3박스/총90포 27900 27900 0
ALL ALL 5 1500461683 광동제약공식스토어 [광동]비타500 젤리 x 20팩/간식/비타민c 13600 10900 19
ALL ALL 6 1766274481 해피콜 다이아몬드 후라이팬 1+1 (팬28/궁중28) +사은품 39900 39900 0
ALL ALL 7 2095691409 스마일배송 [유한킴벌리]크리넥스3겹 울트라클린27MX30롤X2팩 33000 33000 0
ALL ALL 8 2273879593 스타쉽스퀘어 (Jewel Case Ver. SET) MONSTA X Mini Album - NO LIMIT (몬스타엑스 미니10집 5종 세트) 55000 55000 0
ALL ALL 9 2223817994 블루독패밀리 [래핑차일드]래핑차일드PLAY_Z 스웨트팬츠 (81W79-402-01) 29900 14950 50
ALL ALL 10 2128333213 모노시크01 모노시크/20%/기모티셔츠/맨투맨/가디건/니트/바지 19700 7900 59
ALL ALL 11 2277677383 AppleMusic (한정반/예약특전) 스트레이 키즈 (Stray Kids) - Holiday Special Single Christmas EveL 13400 13400 0
ALL ALL 12 2266613663 SK스토아TV쇼핑 어썸핏 21FW 테이퍼드핏 기모 본딩팬츠 3종 49900 45410 8
ALL ALL 13 2265957737 신세계백화점 [블랙야크키즈](신세계하남점)[블랙야크키즈] 한겨울   롱패딩 2종1택 [정상가 338000원 모듈다운자켓L 피어L다운자켓] 99000 75240 24
ALL ALL 14 1945625935 옴백 절임배추 20kg 9포기내외 강원도 영월 고랭지 배추 35900 35550 0
ALL ALL 15 1513973750 메이킹유 쿠폰20% 맨투맨/원피스/블라우스/스커트/기모바지 33300 10000 69
ALL ALL 16 1498699891 (주)이지바이 [이지바이](20%쿠폰)놓쳐서는 안될 겨울아웃도어/아우터/티/바지 26300 7900 69
ALL ALL 17 2224738312 YOMI02 남녀공용 오리털 파카 덕다운 후드 숏패딩 겨울패딩 27800 23330 16
ALL ALL 18 2245422156 스마일배송 [그린몬스터]디톡 콤부차 레몬홍차 6박스+보틀 증정 / 20억 유산균 24000 19900 17
ALL ALL 19 495818668 ★젤리스푼★ [젤리스푼]아동복/아동의류/키즈경량패딩/레깅스/원피스/뽀글이 33000 9900 70
ALL ALL 20 2259650977 스마일배송 [닥터그루트]닥터그루트 탈모완화샴푸 빅스마일데이 패키지 87000 48000 44
ALL ALL 21 1505743733 세타필총판 [세타필]세타필 대용량1+1(로션 473ml+로션 473ml) +미니5종 39000 24900 36
ALL ALL 22 2258172855 글뿌리출판 우리아이 첫 경제 입문동화 호기심빵빵 경제동화 56000 51420 8
ALL ALL 23 1604479096 아기물티슈베베앙 [베베앙]베베앙 아기물티슈  시그니처 대용량 100매 캡형 10팩 25800 12900 50
ALL ALL 24 1961878399 ohbook6 씨투엠 수학 교구상자 펜토미노턴/큐브빌드 선택구매(워크북포함)(NEW) 65000 43500 33
ALL ALL 25 1912472472 롯데백화점2관 [컬럼비아][컬럼비아] 남여 플리스 자켓 C24-WE3220 40500 29970 26
ALL ALL 26 1345149344 brich 브리치x럭키567 20%+10%쿠폰 맨투맨/패딩/니트 46300 13900 69
ALL ALL 27 2036523446 콘텐트리 Ditty Bird 음악과 소리로 즐기며 배우는 영어사운드북 14종 선택구매 18000 9000 50
ALL ALL 28 2273879425 스타쉽스퀘어 (Jewel Case Ver. SET/Ver SET) MONSTA X Mini Album - NO LIMIT (몬스타엑스 미니10집 9종 세트) 120200 120200 0
ALL ALL 29 959734579 피죤공식몰 [피죤]섬유유연제 3100ml x3개 핑크+피죤1L/하루특가7500원 23800 11900 50
ALL ALL 30 2247122550 (주)한국선불카드 [구글플레이](Google Play 기프트코드) 10만원 / 구글 기프트카드 100000 93000 7

 

(이하 생략)

```

 

G마켓의 Best 페이지에서 메인/서브 카테고리명, 메인/서브 카테고리의 상품 정보, 상품코드, 판매자 정보를 크롤링으로

가져온 결과이다.

 

위의 예시코드에서 if-else문은 크롤링한 데이터가 일부 누락되면서 발생할 수 있는 에러를 방지하기 위한 코드이다.

또한, if문에서 if ori_price.get_text() == '' or ori_price == None: 코드로 작성하면 변수 ori_price가 데이터가

누락되어 None 값을 가지는 순간 에러가 발생하고 코드 전체가 실행을 멈춘다. (예시코드처럼 if문을 작성하는 이유)

 

 

크롤링한 데이터를 스키마(Schema)에 저장하기(실전 연습)

import requests
from bs4 import BeautifulSoup
import pymysql

def save_data(item_info):
    print (item_info)
    sql = """SELECT COUNT(*) FROM items WHERE item_code = '""" + item_info['item_code'] + """';"""
    cursor.execute(sql)
    result = cursor.fetchone()
    print (result[0])
    if result[0] == 0:
        sql = """INSERT INTO items VALUES('""" + item_info['item_code'] + """',
        '""" + item_info['title'] + """', 
        """ + str(item_info['ori_price']) + """, 
        """ + str(item_info['dis_price']) + """, 
        """ + str(item_info['discount_percent']) + """, 
        '""" + item_info['provider'] + """')"""
        print(sql)
        cursor.execute(sql)
    
    sql = """INSERT INTO ranking (main_category, sub_category, item_ranking, item_code) VALUES('""" + item_info['category_name'] + """',
    '""" + item_info['sub_category_name'] + """', 
    '""" + str(item_info['ranking']) + """', 
    '""" + item_info['item_code'] + """')"""     
    print(sql)
    cursor.execute(sql)
    
    
def get_item(html, category_name, sub_category_name):
    best_item = html.select('div.best-list')
    for index, item in enumerate(best_item[1].select('li')):
        data_dict = dict()
        
        ranking = index + 1
        title = item.select_one('a.itemname')
        ori_price = item.select_one('div.o-price')
        dis_price = item.select_one('div.s-price strong span')
        discount_percent = item.select_one('div.s-price em')
        
        if ori_price == None or ori_price.get_text() == '':
            ori_price = dis_price
        
        if dis_price == None:
            ori_price, dis_price = 0, 0
        else:
            ori_price = ori_price.get_text().replace(',', '').replace('원', '')
            dis_price = dis_price.get_text().replace(',', '').replace('원', '')
        
        if discount_percent == None or discount_percent.get_text() == '':
            discount_percent = 0
        else:
            discount_percent = discount_percent.get_text().replace('%', '')
        
        product_link = item.select_one('div.thumb > a')
        item_code = product_link.attrs['href'].split('=')[1].split('&')[0]
        
        res = requests.get(product_link.attrs['href'])
        soup = BeautifulSoup(res.content, 'html.parser')
        provider = soup.select_one('div.item-topinfo_headline > p > span > a')
        if provider == None:
            provider = ''
        else:
            provider = provider.get_text()
        
        data_dict['category_name'] = category_name
        data_dict['sub_category_name'] = sub_category_name
        data_dict['ranking'] = ranking
        data_dict['title'] = title.get_text()
        data_dict['ori_price'] = ori_price
        data_dict['dis_price'] = dis_price
        data_dict['discount_percent'] = discount_percent
        data_dict['item_code'] = item_code
        data_dict['provider'] = provider
        
        save_data(data_dict)
 

def get_category(category_link, category_name):
    print(category_link, category_name)
    res = requests.get(category_link)
    soup = BeautifulSoup(res.content, 'html.parser')
    
    get_item(soup, category_name, 'ALL')
    
    sub_categories = soup.select('div.navi.group ul li > a')
    for sub_category in sub_categories:
        res = requests.get('http://corners.gmarket.co.kr/' + sub_category['href'])
        soup = BeautifulSoup(res.content, 'html.parser')
        get_item(soup, category_name, sub_category.get_text())
        
       
db = pymysql.connect(host='localhost', port=3306, user='root', passwd='mysql pw', db='bestproducts', charset='utf8')
cursor = db.cursor()

res = requests.get('http://corners.gmarket.co.kr/Bestsellers')
soup = BeautifulSoup(res.content, 'html.parser')

categories = soup.select('div.gbest-cate ul.by-group li a')
for category in categories:
    get_category('http://corners.gmarket.co.kr/' + category['href'], category.get_text())

db.commit()
db.close()

 

```

결과 :

http://corners.gmarket.co.kr//Bestsellers ALL
{'category_name': 'ALL', 'sub_category_name': 'ALL', 'ranking': 1, 'title': '에이티즈 (ATEEZ) - 2022 SEASONS GREETINGS 시즌그리팅', 'ori_price': '40000', 'dis_price': '40000', 'discount_percent': 0, 'item_code': '2278015861', 'provider': 'AppleMusic'}
0
INSERT INTO items VALUES('2278015861',
        '에이티즈 (ATEEZ) - 2022 SEASONS GREETINGS 시즌그리팅', 
        40000, 
        40000, 
        0, 
        'AppleMusic')
INSERT INTO ranking (main_category, sub_category, item_ranking, item_code) VALUES('ALL',
    'ALL', 
    '1', 
    '2278015861')
{'category_name': 'ALL', 'sub_category_name': 'ALL', 'ranking': 2, 'title': '[아토세이프]최종가 9970원/ 쉬슬러 고농축 세제 3.05L 2개+증정', 'ori_price': '17900', 'dis_price': '13900', 'discount_percent': '22', 'item_code': '1743943703', 'provider': '스마일배송'}
0
INSERT INTO items VALUES('1743943703',
        '[아토세이프]최종가 9970원/ 쉬슬러 고농축 세제 3.05L 2개+증정', 
        17900, 
        13900, 
        22, 
        '스마일배송')
INSERT INTO ranking (main_category, sub_category, item_ranking, item_code) VALUES('ALL',
    'ALL', 
    '2', 
    '1743943703')
{'category_name': 'ALL', 'sub_category_name': 'ALL', 'ranking': 3, 'title': '[안흥찐빵]원조 안흥 할매 쌀 찐빵 / 30개  5%중복쿠폰', 'ori_price': '22000', 'dis_price': '9900', 'discount_percent': '55', 'item_code': '197096950', 'provider': '좋은아침'}
0

 

(이하 생략)

```

 

G마켓의 Best 페이지에서 메인/서브 카테고리명, 메인/서브 카테고리의 상품 정보, 상품코드, 판매자 정보를 크롤링으로

가져와서 데이터베이스에 입력한 결과이다. (프로그래밍을 사용하여 데이터베이스에 데이터 입력)

 

save_data() 함수를 통해 테이블 ranking에 데이터를 먼저 입력하면 에러가 발생한다.

즉, Foreign Key를 고려하여 items 테이블에 데이터를 먼저 입력한 후에 ranking 테이블에 데이터를 입력해야 한다.

 

참고로, 프로그래밍을 통해 크롤링한 데이터를 데이터베이스에 입력하는 경우에는 반드시 1~2개의 데이터를 연습삼아

먼저 넣어서 잘 입력되는지를 확인한 후에 나머지 데이터를 입력하는 것이 좋다. (에러 발생 가능성 감소)

 

 

참고 내용

  • 파이썬 코드로 데이터베이스 테이블 삭제하기
import pymysql
db = pymysql.connect(host='localhost', port=3306, user='root', passwd='mysql pw', db='besttest', charset='utf8')
cursor = db.cursor()

sql = "DELETE FROM ranking"
cursor.execute(sql)

sql = "DELETE FROM items"
cursor.execute(sql)

db.commit()
db.close()

 

테이블을 삭제할 때에도, ranking 테이블을 먼저 삭제한 후에 items 테이블을 삭제해야 한다.

즉, Foreign Key와 테이블 간의 관계를 고려하여 Foreign Key가 있는 테이블을 우선 삭제해야 한다. 

 

'Database' 카테고리의 다른 글

MySQL - 서브쿼리 활용  (0) 2021.11.15
MySQL - 데이터 분석과 SQL 문법  (0) 2021.11.12
MySQL - Foreign Key  (0) 2021.11.11
MySQL - pandas & pymysql 라이브러리  (0) 2021.11.10
MySQL - 파일로 실행하는 SQL  (0) 2021.11.10

댓글