goodthings4me.tistory.com
쇼핑몰 도매사이트 온 채널의 명예의 전당(매년 많이 팔린 상품)에 있는 우수상품 리스트를 파이썬으로 크롤링하는 코드이다. 작년에 짜 놓은 코드에서 오류 나는 부분만 수정해서 포스팅함
온채널 도매사이트 우수상품 크롤링
[파이썬 소스 코드]
import requests
from bs4 import BeautifulSoup as bts4
from urllib.parse import urljoin
import time
import random
import openpyxl
import os
def onch3_halloffame(page):
onch3 = 'https://www.onch3.co.kr'
## 폴더 생성
if not os.path.exists('./onch3'):
os.makedirs('./onch3')
if not os.path.exists('./image'):
os.makedirs('./image')
## 엑셀 제목
theme_list = ['no', 'prd_code', 'prd_name', 'prd_url', 'onch_category', 'product_name', \
'keywords', 'smartstore_code', 'smartstore_category', 'product_name2', 'supp_grade', \
'supp_title', 'price_type', 'deliver', 'deadline_time', 'product_status', 'entry_date']
## 엑셀 워크북(파일) 생성 후 열 제목 추가
workbook_name = 'onch3_2021_best1000.xlsx'
wb = openpyxl.Workbook()
wb.save('./onch3/' + workbook_name)
ws = wb['Sheet']
ws.append(theme_list)
wb.save('./onch3/' + workbook_name)
cnt = 0 # 추출 리스트 카운트 cnt = 0
row = 1 # 행 번호
for page in range(1, page + 1):
url = 'https://www.onch3.co.kr/onch_hall_of_fame.html?sec=2021&page=' + str(page)
# url = 'https://www.onch3.co.kr/onch_hall_of_fame.html?sec=best&page=' + str(page) # 금년도
response = requests.get(url)
response.encoding = 'utf-8'
soup = bts4(response.text, 'html.parser')
## 'ul.prd_list' 1개 / 'ul.prd_list > li' 40개
ul_lis = soup.select('ul.prd_list > li')
products = []
for li in ul_lis:
for ls in li.select('ul.prd_info'):
cnt += 1
row += 1
details = {}
prd_code = ls.find('li', class_='prd_code').get_text().split(' : ')[1].strip()
prd_name = ls.find('li', class_='prd_name').text
prd_link = ls.find('li', class_='btn_sale').find('a')['href']
sub_url = urljoin(onch3, prd_link)
# print(prd_code, prd_name, sub_url)
details['prd_code'] = prd_code
details['prd_name'] = prd_name
details['prd_url'] = sub_url
time.sleep(random.uniform(0.5, 1))
## 상품 상세페이지 스크래핑 - requests
sub_response = requests.get(sub_url)
sub_response.encoding = 'utf-8'
sub_soup = bts4(sub_response.text, 'html.parser')
## 온채널 카테고리
onch_cate = sub_soup.find('div', class_='detail_page_category').text.strip()
details['onch_category'] = onch_cate
## 상품 상세정보
prd_detail = sub_soup.select('div.prod_detail_box > ul > li')
# 상품명
product_name = prd_detail[0].text.strip()
details['product_name'] = product_name
# 추천키워드
keywords = prd_detail[1].find('div', class_='prod_keyword').text.strip()
# 온채널 추천키워드 내 '#'과 '공란' 제거 후 '#'으로 분리, 리스트 중 '공백' 제거하기
keywords = [word for word in keywords.replace('#', '#').replace(' ', '').split('#') if word != '']
details['keywords'] = keywords
# 스마트스토어 카테고리 코드
smartstore_code = prd_detail[1].find('div', class_='prod_ss_cate').find('span', class_='ss_cate_num').text.strip()
details['smartstore_code'] = smartstore_code
# 스마트스토어 카테고리
smartstore_cate = prd_detail[1].find('div', class_='prod_ss_cate').text[9:].strip()
details['smartstore_category'] = smartstore_cate
## 제품명/제품코드/공급업체분류/공급사페이지
# 상품명
product_name2 = prd_detail[2].find('div', class_='prod_detail_title_2').text.strip()
details['product_name2'] = product_name2
# 공급사 평점
supp_grade = prd_detail[2].find('div', class_='sup_grade hidden_element').find('dt').text.strip()
details['supp_grade'] = supp_grade
# 공급업체분류
supp_title = ' '.join(prd_detail[2].find_all('li')[2].text.strip().split()) # 다중 공백을 1개로 치환 - 문자열
details['supp_title'] = supp_title
# 공급사 페이지 - 인증 회원만 열람 가능
#supp_hpage = prd_detail[2].find_all('li')[3].find('a')['href']
## 소비자가/판매자공급가/운영채널분류 등
# 운영체제 분류
price_type = prd_detail[3].find_all('li')[2].text.strip().split() # 다중 공백을 1개로 치환 - 리스트
details['price_type'] = price_type
# 배송비/택배사
deliver = ' '.join(prd_detail[4].find_all('li')[0].text.strip().split())
details['deliver'] = deliver
# 마감/발송처/기간
deadline_time = ' '.join(prd_detail[4].find_all('li')[1].text.strip().split())
details['deadline_time'] = deadline_time
# 제품상태/입정일자
product_status = prd_detail[5].find_all('li')[0].text.strip().split()
details['product_status'] = product_status
entry_date = prd_detail[5].find_all('li')[1].text.strip().split()
details['entry_date'] = entry_date
time.sleep(random.uniform(0.5, 1))
### 엑셀에 추출 데이터 저장하기
for k, v in details.items():
ws.cell(row, 1).value = cnt
if k == 'prd_code':
ws.cell(row, 2).value = v
if k == 'prd_name':
ws.cell(row, 3).value = v
if k == 'prd_url':
ws.cell(row, 4).value = v
if k == 'onch_category':
ws.cell(row, 5).value = v
if k == 'product_name':
ws.cell(row, 6).value = v
if k == 'keywords':
keyWords = ''
for word in keywords:
keyWords = keyWords + '$' + word
ws.cell(row, 7).value = keyWords
if k == 'smartstore_categCode':
ws.cell(row, 8).value = v
if k == 'smartstore_category':
ws.cell(row, 9).value = v
if k == 'product_name2':
ws.cell(row, 10).value = v
if k == 'supp_grade':
ws.cell(row, 11).value = v
if k == 'supp_title':
ws.cell(row, 12).value = v
if k == 'price_type':
priceType = ''
for word in price_type:
priceType = priceType + '$' + word
ws.cell(row, 13).value = priceType
if k == 'deliver':
ws.cell(row, 14).value = v
if k == 'deadline_time':
ws.cell(row, 15).value = v
if k == 'product_status':
productStatus = ''
for word in product_status:
productStatus = productStatus + '$' + word
ws.cell(row, 16).value = productStatus
if k == 'entry_date':
entryDate = ''
for word in entry_date:
entryDate = entryDate + '$' + word
ws.cell(row, 17).value = entryDate
wb.save('./onch3/' + workbook_name)
time.sleep(random.uniform(0.5, 1))
## 대표 이미지 받기
product_imgs = sub_soup.select('div.prod_detail_imgbox > a > img')
img_cnt = 1
for img in product_imgs:
try: # 이미지가 없어서 발생하는 오류 방지
print(img['src'])
image = requests.get(img['src']).content
except:
print('Error - 이미지 오류!!')
pass
# 폴더명 특수문자 제거
special_char = '\/:*?"<>|\t' # 폴더명에 탭(\t) 들어간 경우
keywords[0] = ''.join(c for c in keywords[0] if c not in special_char)
# keyWords[0] = keyWords[0].replace('\t', '')
path = './image/' + prd_code + '_' + keywords[0]
if not os.path.exists(path):
os.mkdir(path)
filename = prd_code + '_' + str(img_cnt) + '.jpg'
print(filename)
with open(f'{path}/{filename}', 'wb') as img:
img.write(image)
img_cnt += 1
time.sleep(random.uniform(0.5, 1))
## 제품 상세 내용 이미지
product_detail_imgs = sub_soup.select('div.content_section img')
imgs_cnt = 1
for img in product_detail_imgs:
try: # 이미지가 없어서 발생하는 오류 방지
print(img['src'])
images = requests.get(img['src']).content
except:
print('Error - 이미지 오류!!')
pass
file_name = prd_code + '_' + 'detail' + '_' + str(imgs_cnt) + '.jpg'
print(file_name)
with open(f'{path}/{file_name}', 'wb') as image:
image.write(images)
imgs_cnt += 1
products.append(details)
print(cnt)
print(f'\n{products}\n\n{page}페이지 리스트 추출 및 엑셀 저장 완료!!\n')
if __name__ == '__main__':
page = 2
onch3_halloffame(page)
- 우수상품 하단에 페이지 번호가 있다. 이 부분에서 끝 페이지 번호를 알아낸 후 page 변수에 페이지 번호를 대입하고 프로그램을 실행하면 된다. (단, 전체 페이지를 한번에 추출하는 것은 자제!)
- 우수상품을 클릭하면 상세페이지가 나오는데, 추천 키워드, 스마트 스토어 카테고리, 제품명, 제품 코드 공급사 평점, 배송비/택배비, 입점 일자 등의 내용을 추출하여 엑셀에 저장을 한다.
- 이미지 폴더를 생성하고 제품명을 폴더명으로 하여 생성 후 대표이미지와 상세 이미지를 다운로드한다.
[실행 결과]
https://image.onch3.co.kr/img_data/2021/1622682235_img80.jpg
CH1506009_1.jpg
https://image.onch3.co.kr/img_data/2021/1627956429_img75.jpg
CH1506009_detail_1.jpg
https://image.onch3.co.kr/img_data/2021/1627956494_img25.jpg
CH1506009_detail_2.jpg
1
https://image.onch3.co.kr/img_data/2020/1599619131_img89.jpg
CH1320982_1.jpg
https://image.onch3.co.kr/ext_image/2017/2017_06/CH1320982_20170602_0169.jpg
CH1320982_detail_1.jpg
https://image.onch3.co.kr/ext_image/2017/2017_06/CH1320982_20170602_0170.gif
CH1320982_detail_2.jpg
https://image.onch3.co.kr/ext_image/2017/2017_06/CH1320982_20170602_0171.jpg
CH1320982_detail_3.jpg
https://image.onch3.co.kr/ext_image/2017/2017_06/CH1320982_20170602_0172.jpg
CH1320982_detail_4.jpg
https://image.onch3.co.kr/ext_image/2017/2017_06/CH1320982_20170602_0173.jpg
CH1320982_detail_5.jpg
https://image.onch3.co.kr/ext_image/2017/2017_06/CH1320982_20170602_0174.jpg
CH1320982_detail_6.jpg
https://image.onch3.co.kr/ext_image/2017/2017_06/CH1320982_20170602_0175.jpg
CH1320982_detail_7.jpg
https://image.onch3.co.kr/ext_image/2017/2017_06/CH1320982_20170602_0176.jpg
CH1320982_detail_8.jpg
https://image.onch3.co.kr/ext_image/2017/2017_06/CH1320982_20170602_0177.jpg
CH1320982_detail_9.jpg
https://image.onch3.co.kr/ext_image/2017/2017_06/CH1320982_20170602_0178.jpg결과
.
.
'코딩 연습 > 파이썬 크롤링' 카테고리의 다른 글
스마트 스토어 데이터 크롤링하여 sqlite3에 저장하기 (0) | 2022.06.02 |
---|---|
다음 뉴스 기사 제목 본문 크롤링 후 텍스트 저장 (0) | 2022.06.01 |
구글 이미지 검색 후 크롤링 (0) | 2022.05.20 |
네이버 인플루언서 탭에서 인플루언서의 이름과 팬 숫자 추출하기 (0) | 2022.05.18 |
네이버 뉴스 크롤링 - 기사 제목과 링크(URL) 추출 (0) | 2022.05.16 |
댓글