본문 바로가기
코딩 연습/파이썬 크롤링

스마트 스토어 데이터 크롤링하여 sqlite3에 저장하기

by good4me 2022. 6. 2.

goodthings4me.tistory.com

[파이썬 크롤링] 네이버 쇼핑에 노출되는 스마트 스토어의 상품 데이터를 크롤링 후 sqlite3 db에 저장하는 방법을 정리한다.

 

 

Python으로 크롤링한 데이터를 DB(sqlite3)에 저장해 보기

 

1. 스마트 스토어 쇼핑몰 상품 스크래핑하기

from os import execlpe
import requests
from bs4 import BeautifulSoup
import json, re
import pandas as pd
import sqlite3


def nshopping_sstore(uid):
    url = f'https://smartstore.naver.com/{uid}'

    headers = {
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36',
    }

    r1 = requests.get(url, headers=headers)
    if r1.status_code == 200:
        soup = BeautifulSoup(r1.text, 'html.parser')
        scripts = soup.find('body').find_all('script')

        # 앞 window.__PRELOADED_STATE__= 부분 삭제
        data = scripts[0].text.strip()[27:]
        
        r2 = json.loads(data)

        item_cnt = 0
        itemsList =[]
        for dict_elem in r2['widgetContents']['wholeProductWidget']['A']['data']:  # 상품전체 부분을 대상으로 함
            name = dict_elem['name']
            items ={
                'name': dict_elem['name'],
                'id': dict_elem['id'],
                'categoryId': dict_elem['category']['categoryId'],
                'categoryName': dict_elem['category']['wholeCategoryName'],
                'channelName': dict_elem['channel']['channelName'],
                'productNo': dict_elem['productNo'],
                'salePrice': dict_elem['salePrice'],
                'productStatusType': dict_elem['productStatusType'],
                'discountedSalePrice': dict_elem['benefitsView']['discountedSalePrice'],
                'discountedRatio': dict_elem['benefitsView']['discountedRatio'],
                'textReviewPoint': dict_elem['benefitsView']['textReviewPoint'],
                'photoVideoReviewPoint': dict_elem['benefitsView']['photoVideoReviewPoint'],
                'reviewCount': dict_elem['reviewAmount']['totalReviewCount'],
                'averageReviewScore': dict_elem['reviewAmount']['averageReviewScore'],
                'representativeImageUrl': dict_elem['representativeImageUrl']
            }
            itemsList.append(items)
            item_cnt += 1

        print(itemsList)

        print(item_cnt)

    ## pandas로 출력
    df = pd.DataFrame(itemsList)
    print(df.head())

    ## 엑셀로 저장
    df.to_excel(uid + '.xlsx', index=False)


nshopping_sstore('판매자ID')

- 엑셀 저장 파일명은 판매자 ID이며, 아래와 같은 json() 관련 오류 메시지 발생 시, data에 이모지(emoji) 내용이 있는지 확인하고, 있을 경우 이모지 제거를 해본 후 다시 실행한다. (이모지 제거 관련 내용은 여기 참고)

 

good4me.co.kr

 

2. 추출 데이터를 sqlite3에 저장해 보기

## table 새성
def create_table(tb_name):
    conn = sqlite3.connect('tempdb.db')
    cur = conn.cursor()
    try:
        cur.execute(f'CREATE TABLE {tb_name + "_tb"}(name TEXT, id TEXT, categoryId TEXT, categoryName TEXT, channelName TEXT, \
            productNo TEXT, salePrice INT, productStatusType TEXT, discountedSalePrice INT, discountedRatio TEXT, \
            textReviewPoint TEXT, photoVideoReviewPoint TEXT, reviewCount TEXT, averageReviewScore TEXT, representativeImageUrl TEXT)'
        )
        print('CreateTable Success!!')
    except Exception as e:
        print('CreateTable Error:', e)  # CreateTable Error: table borame365_tb already exists
        return False
    return True
    
    
    
## 추출 데이터 저장

def save_data(uid):
    # create_res = create_table(uid)
    # print(create_res)

    conn = sqlite3.connect('tempdb.db')
    cur = conn.cursor()

    for item in itemsList:
        res = cur.execute(f'INSERT INTO {uid + "_tb"} VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', (item['name'], item['id'], \
            item['categoryId'], item['categoryName'], item['channelName'], item['productNo'], item['salePrice'], \
            item['productStatusType'], item['discountedSalePrice'], item['discountedRatio'], item['textReviewPoint'], \
            item['photoVideoReviewPoint'], item['reviewCount'], item['averageReviewScore'], item['representativeImageUrl'])
        )
        print(res)  # <sqlite3.Cursor object at 0x0000024317D352D0>
    conn.commit()
    print('커밋 완료')

    rs = cur.execute(f'SELECT * FROM {uid + "_tb"}')

    print(f'rs:\n{rs}')  # <sqlite3.Cursor object at 0x000001DFDC866340>
    for r in rs:
        print(r)  # tuple() 리턴

    rs2 = cur.execute(f'SELECT * FROM {uid + "_tb"}')
    results = rs2.fetchall()
    print(results)  # [(), (),...]

    cur.execute(f'DELETE FROM {uid + "_tb"}')
    conn.commit()
    print('삭제 완료!!')

    cur.close()


save_data('테이블명')

- 테이블은 테이블명은 create_table() 함수를 호출해서 만들고, '테이블명_tb'로 생성된다.

- 테이블이 생성되면, 아래 코드는 주석 처리해야 한다.

create_res = create_table(uid)
print(create_res)

- 테이블이 잘 못 생성되었을 경우, 테이블 삭제는

cur.execute(f'DROP TABLE {uid + "_tb"}')

  
상기 소스코드 내용은,

하나의 네이버 쇼핑 판매자 몰의 상품 리스트를 추출하여 엑셀에 저장하고, sqlite3 저장을 하는 코드이지만 연습용으로 하기 위해 db table에 insert 한 자료는 바로 삭제되도록 했다.

 

 

댓글