ranking 테이블의 경우 카테고리마다 랭킹이 있으므로 PRIMARY KEY를 랭킹 정보로 사용할 수는 없다. 따라서 따로 num이라는 칼럼을 PRIMARY KEY로 설정한다. items 테이블의 item_code를 외래키로 참조한다.
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(20) NOT NULL,
FOREIGN KEY(item_code) REFERENCES items(item_code)
);
items 테이블은 해당 item에 대한 정보를 담고 있는 테이블이다.
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)
);
2. Schema 구현
터미널 환경이나 Workbench에서 데이터베이스를 생성한다.
CREATE DATABASE bestproducts;
USE bestproducts;
그 이후부터는 pymysql에서 작업을 하겠다.
✋주의사항✋ 테이블을 생성할 때, ranking 테이블을 먼저 생성해서 안된다. FOREIGN KEY로 사용할 items 테이블의 item_code가 아직 정의되어있지 않기 때문이다. 따라서 items 테이블을 먼저 생성한다.
import pymysql
db = pymysql.connect(host='localhost', port=3306, user='root', password='rlaqufgml!23', db='bestproducts', charset='utf8')
cursor = db.cursor()
sql = '''
CREATE TABLE items (
item_code VARCHAR(10) 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(20) NOT NULL,
FOREIGN KEY(item_code) REFERENCES items(item_code)
);
'''
cursor.execute(sql)
db.commit()
db.close()
3. 데이터 크롤링
3.1 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())
output
3.2 sub category 정보 크롤링
sub category는 main category를 클릭하면 밑에서 확인할 수 있다.
따라서 requests.get('http://corners.gmarket.co.kr/Bestsellers?viewType=G&groupCode=G01')로 부터 정보를 가져와야 한다.
main category와 sub category
따라서 링크와 카테고리 이름을 입력하면,
sub_category의 이름과 링크를 출력하는 함수를 정의하였다.
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('http://corners.gmarket.co.kr/'+ sub_category['href'], sub_category.get_text())
category 정보를 가져와 get_category 함수를 이용해 sub_category 정보를 가져왔다.
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_items(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_items(soup, category_name, sub_category.get_text())
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())