인프런 커뮤니티 질문&답변

성훈님의 프로필 이미지

작성한 질문수

[2024 리뉴얼] 처음하는 SQL과 데이터베이스(MySQL) 부트캠프 [입문부터 활용까지]

mysql [실전] 크롤링과 데이터베이스 db와 프로그래밍 코드 작성과 팁 2 질문입니다

21.07.16 22:28 작성

·

400

0

훌륭한 강의 잘 듣고있는 코린이입니다

수업 들으면서 코드 복습도 하곤 하는데

크롤링한 데이터를 주피터 노트북을 이용하여 데이터베이스에 저장시키는건 잘 되는데, 파이참이나 vscode 터미널 등에서 실행하면 맨 처음 데이터만 프린트 문으로 보여주고 파일은 실행되지않고 있다가

pymysql.err.OperationalError: (1205, 'Lock wait timeout exceeded; try restarting transaction')

이런 에러가 뜹니다

혼자 해결해보려고 했으나 도저히 모르겠어서 질문남깁니다! 꼭 답변부탁드려요!!

import requests
from bs4 import BeautifulSoup
import pymysql

def subcategories(url, name):
    get_items(url, name, "ALL")
    
    
    res = requests.get(url)
    soup = BeautifulSoup(res.content, 'html.parser')
    
    subcategories = soup.select('div.navi.group > ul:nth-child(1) > li')
    for subcategory in subcategories :

        subcate_name = subcategory.select_one('a').get_text()
        subcate_url = "http://corners.gmarket.co.kr" + subcategory.select_one('a')['href']
        
        get_items(subcate_url, maincate_name, subcate_name)

def get_items(url, maincate_name, subcate_name):
    res = requests.get(url)
    soup = BeautifulSoup(res.content, 'html.parser')
    
    data = soup.select('div.best-list')
    for index, item in enumerate(data[1].select('li')) :
        title = item.select_one('a.itemname').get_text()
        ori_price = item.select_one('div.o-price > span')
        dis_price = item.select_one('div.s-price > strong > span')
        discount_percent = item.select_one('div.s-price em')
        
        data_dict = dict()
        
        if ori_price == None or ori_price.get_text() == "":
            ori_price = dis_price
        
        if dis_price == None :
            ori_price, dis_price = 0, 0
        else :
            dis_price = dis_price.get_text().replace('원', "").replace(',','')
            ori_price = ori_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_url = item.select_one('a')['href']
        res = requests.get(product_url)
        soup = BeautifulSoup(res.content, 'html.parser')
        
        item_code = soup.select_one('span.text__item-number').get_text().split(":")[1].strip()
        ranking = index + 1

        seller = soup.select_one('span.text__seller > a')
        if seller == None or seller.get_text() == "":
            seller = ""
        else :
            seller = seller.get_text()
        
        data_dict['maincate_name'] = maincate_name
        data_dict['subcate_name'] = subcate_name
        data_dict['ranking'] = ranking
        data_dict['item_code'] = item_code
        data_dict['seller'] = seller
        data_dict['title'] = title
        data_dict['ori_price'] = ori_price
        data_dict['dis_price'] = dis_price
        data_dict['discount_percent'] = discount_percent
        
        save_date(data_dict)

def save_date(item_info):    
    sql = f"""select count(*) from items where item_code = {item_info['item_code']};"""
    cursor.execute(sql)
    result = cursor.fetchone()
    if result[0] == 0 :
        sql = f"""
        insert into items (item_code, title, pri_price, dis_price, discount_percent, provider) VALUES(
        '{item_info['item_code']}',
        '{item_info['title']}',
        {item_info['ori_price']},
        {item_info['dis_price']},
        {item_info['discount_percent']},
        '{item_info['seller']}'
        );
        """
        sql.replace('\n', '')
        print(sql)
        cursor.execute(sql)
        
    sql = f"""
    insert into ranking (main_category, sub_category, item_ranking, item_code) VALUES(
    '{item_info['maincate_name']}',
    '{item_info['subcate_name']}',
    '{item_info['ranking']}',
    '{item_info['item_code']}'
    );
    """
    sql.replace('\n', '')
    print(sql)
    cursor.execute(sql)

db = pymysql.connect(host='localhost', port=3306, user='root', passwd='비밀번호', db='bestproducts', charset='utf8')
cursor = db.cursor()

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

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

답변 1

0

잔재미코딩 DaveLee님의 프로필 이미지

2021. 07. 18. 11:02

안녕하세요.

코드가 우선 제가 드린 코드 그대로인지 궁금하네요. 왜냐하면, 그런 에러를 2년간 본적이 없어서요. 무언가 해당 PC와 관련된 특수한 문제로 보여요.

일단은 그 부분은 SQL 실행 시간이 타임아웃이 날 정도로 시간이 초과했다라는 것인데요. DB에 데이터가 너무 많아서, 그런것일 수 있을까요? 해당 테이블도 새로 만들어서 테스트해보셔도 좋을 것 같고요.

또, cursor.execute() 한 후에, 아예 db.close() 등으로 데이터베이스를 닫고, 또 다른 SQL 을 실행할 때, 새로 connection 을 맺는 것 부터, execute(), close() 를 실행해보시는 것은 어떨까요?

아니면, 다음 링크와 같이 mysql 터미널로 접속해서, 

https://jaenjoy.tistory.com/26

위 링크에서 제안한 명령으로 타임아웃을 늘려보시면 어떨까요?

SET GLOBAL innodb_lock_wait_timeout=20;
성훈님의 프로필 이미지

작성한 질문수

질문하기