{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## 실제 사이트 크롤링 - 신세계 인터넷 쇼핑몰" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import bs4\n", "import requests as rq\n", "import pandas as pd" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1. 사이트에 접속하고 탐색해 본다:" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. 먼저 다음 사이트에 들어가서 살펴본다: [신세계 건강식품](http://department.ssg.com/disp/category.ssg?dispCtgId=3500003739&page=1)\n", "2. 크롬에서 3점 메뉴 버튼을 누르고 **도구 더보기** ==> **개발자 도구**를 선택해서 개발자 도구를 연다.\n", "3. 개발자 도구 왼쪽 상단의 화살표 버튼을 눌러서 사이트 일부를 서택하고 해당 HTML코드를 볼 수 있다. \"[CTRL] + [SHIFT] + C\" 조합으로 대체할 수 있다." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# 웹사이트의 URL에 접속.\n", "# Headers 필요.\n", "my_url = \"http://department.ssg.com/disp/category.ssg?dispCtgId=3500003739&page=\"\n", "my_headers = {\"User-Agent\": \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36\"}\n", "res = rq.get(url = my_url+str(1),headers = my_headers) # page 1 접속." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "200" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# status_code가 200이면 OK.\n", "# status_code가 4xx이면 접속 오류.\n", "res.status_code" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "my_html = res.content\n", "my_soup = bs4.BeautifulSoup(my_html, 'html.parser') # BeautifulSoup 객체 반환. 'html.parser' 사용." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "bs4.element.Tag" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "my_ul = my_soup.find('ul', class_='cunit_thmb_lst') # 단 하나의 ul 태그.\n", "type(my_ul)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['(특별적립,공지확인필)화애락진 70ml*30포 (30일분)', '(특별적립,공지확인필)황진단 4g*12환 (12일분)', '(특별적립,공지확인필)화애락후 70ml*30포 (30일분)', '(특별적립,공지확인필)굿베이스 홍삼담은 석류 (50ml*30포)', '(특별적립,공지확인필)천녹정 180g*2병 (보자기포장)', '(1월 20일 오후 3시 주문 건까지 설전배송)타히티골드 노니주스 원액 946ml x 2병 SET', '[1월22일 오후4시 주문건까지 명절전배송][백화점선물포장][센트룸] 실버 포맨 + 실버 포우먼 세트', '이너플로라 30캡슐*2EA 배송_유통기한 2020.09.11_[유한건강생활 뉴오리진] 이너플로라 60캡슐_2개월분_여성질유산균 프로바이오틱스_1월 22일 수요일 16시이전 주문건에 한해 명절전 배송', '[1/22일 16시 명절배송마감]트리플러스맨+우먼커플세트', '[1월22일 오후4시 주문건까지 명절전배송][백화점선물포장][센트룸] 포맨 + 포우먼 세트', '[1/22일 16시 명절배송마감]대상웰라이프 뉴케어 당플랜 아셉틱 (200ml x 60팩)', '(특별적립,공지확인필)굿베이스 홍삼담은 블루베리 (50ml*30포)', '(특별적립,공지확인필)아이패스 제이(J) 40ml*30포 (30일분)', '[1/22일 16시 명절배송마감][설선물세트]여성용 멀티비타민 미네랄 (60정) x 2병', '(특별적립,공지확인필)정관장 천녹정편(便) 10g*60포', '(특별적립,공지확인필)천녹톤 (70ml*30포)', '(특별적립,공지확인필)굿베이스 홍삼담은 흑마늘 (50ml*30포)', '[1/22일 16시 명절배송마감][비타민뱅크] 남극 크릴 오일 500 30캡슐 x5개', '(특별적립,공지확인필)천녹정 180g', '[1/22일 16시 명절배송마감]비타민D 1000IU (90정/3개월)', '[1/22일 16시 명절배송마감]달맞이꽃종자유Upgrade/90캡슐x2팩', '[1/22일 16시 명절배송마감][설선물세트]남성용 멀티비타민 미네랄 (60정) x 2병', '(특별적립,공지확인필)홍천웅칸 (30일분)', '(특별적립,공지확인필)천녹톤 (70ml*60포)', '[1/22일 16시 명절배송마감]프로폴리스 스프레이 20ml*3개 세트', '[1월22일 오후4시 주문건까지 명절전배송][백화점선물포장][센트룸] 여성 멀티비타민 실버 포우먼 (50정) x 2통', '[1/22일 16시 명절배송마감]프로폴리스 마누카허니 로젠지(캔디) - 레몬 500g', '(특별적립,공지확인필)알파프로젝트 혈행건강 500mg*60캡슐 (30일분)', '(특별적립,공지확인필)황진단 4g*3환 (3일분)', '[1/22일 16시 명절배송마감][둘코화이버] 구미 사과맛 (4개입 15포)x2팩', '[1/22일 16시 명절배송마감]UMF5+ 마누카꿀 250g+클로버꿀 250g 세트', '[1/22일 16시 명절배송마감]밀크씨슬+/60캡슐', '[1/22일 16시 명절배송마감]수퍼바이오틱스+철분/30캡슐x2팩', '[1/22일 16시 명절배송마감][비타민뱅크] 에버콜라겐코큐 CoQ 84정 x3개', '[1/22일 16시 명절배송마감]오메가3 700 DHA/EPA (60캡슐/2개월)', '[1/22일 16시 명절배송마감]수퍼바이오틱스/60캡슐', '[1/22일 16시 명절배송마감][2020 설 선물] 레이델 폴리코사놀5 (30정) X 4개 세트', '[1/22일 16시 명절배송마감][2020 설 선물] 레이델 폴리코사놀10 (30정) X 3개 세트 + 식물성오메가900 (6캡슐) 증정!', '셀큐브바이오 K크다 6개월 (18BOX)/ ★[기간한정] 가격인하+사은품 / 1/22배송마감-1/28순차출고', '[1/22일 16시 명절배송마감]참홍삼도라지 꿀세트', '[1월22일 오후4시 주문건까지 명절전배송][백화점선물포장][센트룸] 남성 멀티비타민 실버 포맨 (50정) x 2통', '(유통기한 2020.09.11)_[유한건강생활 뉴오리진] 이너플로라 30캡슐_1개월분 여성질유산균 프로바이오틱스_1월 22일 수요일 16시이전 주문건에 한해 명절전 배송', '[1월21일 11시까지 주문 시 명절 전 출고]듀오락 마이크로바이옴7 키즈 유산균 2통 (60일분)+추가 4일분', '[1/22일 16시 명절배송마감]키즈멀티비타민미네랄+키즈츄어블오메가3세트', '셀큐브바이오 K크다 3개월 (9BOX) / ★[기간한정] 가격인하+사은품 / 1/22배송마감-1/28순차출고', '[1/22일 16시 명절배송마감]트리플러스우먼/90캡슐', '(특별적립,공지확인필)알파프로젝트 간건강 600mg*180정 (30일분)', '[1/22일 16시 명절배송마감]루테인+오메가3/60캡슐', '[1/22일 16시 명절배송마감]UMF5+ 마누카꿀 500g+야생화꿀 500g 세트', '(특별적립,공지확인필)알파프로젝트 장건강 500mg*60캡슐 (30일분)', '[1/22일 16시 명절배송마감]트리플러스맨/90캡슐', '[1/22일 16시 명절배송마감]차가버섯진액(80mlX30포)[차가버섯진액100%,쇼핑백동봉]', '[1/22일 16시 명절배송마감]루테인 20 (60캡슐/2개월)', '[1/22일 16시 명절배송마감]비오틴 5000 (100캡슐/100일분)', '[1/22일 16시 명절배송마감]UMF18+ 마누카꿀 250g 세트(250g*2ea)', '[1/22일 16시 명절배송마감][비타민뱅크] 남극 크릴 오일 500 30캡슐 x3개', '[1/22일 16시 명절배송마감][비타민뱅크] 에버콜라겐코큐 CoQ 84정 x6개', '[1/22일 16시 명절배송마감]키즈멀티비타민미네랄구미젤리/60구미', '[1월22일 오후4시 주문건까지 명절전배송][백화점선물포장][센트룸] 남성 멀티비타민 포맨 (50정) x 2통', '(특별적립,공지확인필)굿베이스 홍삼담은 오미자 (50ml*30포)', '[1/22일 16시 명절배송마감]키즈멀티비타민미네랄/90정+키즈수퍼바이오틱스/30포세트', '[1월22일 오후4시 주문건까지 명절전배송][백화점선물포장][센트룸] 여성 멀티비타민 포우먼 (50정) x 4통', '[1/22일 16시 명절배송마감][비타민뱅크] 에버콜라겐코큐 CoQ 84정 x2개', '(특별적립,공지확인필)알파프로젝트 눈건강 500mg*90캡슐 (30일분)', '[1/22일 16시 명절배송마감][동국제약] 크릴오일 세트(벨기에산 크릴오일X2세트)', '[1/22일 16시 명절배송마감][설선물세트]비타민B 콤플렉스 100 (50캡슐) x 2병', '[1/22일 16시 명절배송마감][설선물세트]엽산 400 (100정) x 2병', '[1/22일 16시 명절배송마감]남성+여성멀티비타민미네랄커플세트', '[1/22일 16시 명절배송마감]GNC 비타민D3 2000(500mg90정)', '[1/22일 16시 명절배송마감]대상웰라이프 stay strong 뉴케어 액티브 200ml x 24팩', '[1/22일 16시 명절배송마감][허니코] 100%PureNZ UMF5+ 마누카 허니세트 (250g x 2개)', '[1/22일 16시 명절배송마감]마누카꿀 UMF10+ 2종기획(500g x 2)', '[1/22일 16시 명절배송마감][설선물세트]남성용 멀티비타민 (60정) + 여성용 멀티비타민 (60정)', '[1/22일 16시 명절배송마감]UMF5+ 마누카꿀 500g 2종 세트(500g x 2)', '[1월22일 오후4시 주문건까지 명절전배송][백화점선물포장][센트룸] 여성 멀티비타민 포우먼 (50정) x 2통', '[1월22일 오후4시 주문건까지 명절전배송][센트룸] 여성 멀티비타민 포우먼 (50정)', '[1월22일 오후4시 주문건까지 명절전배송][백화점선물포장][센트룸] 포맨 + 포우먼 세트 x 2통', '[1/22일 16시 명절배송마감]콤비타 UMF5+ 마누카꿀 500g', '[1/22일 16시 명절배송마감]여성을위한멀티비타민미네랄x2팩', '[1/22일 16시 명절배송마감]수퍼바이오틱스/60캡슐x2팩']\n" ] } ], "source": [ "# 이름만 가져와 본다.\n", "my_names = my_ul.select('a em.tx_ko')\n", "my_names_list =[x.text.strip() for x in my_names]\n", "print(my_names_list)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "['144,000', '216,000', '180,000', '42,400', '405,000', '98,000', '48,000', '76,500', '61,740', '48,000', '97,800', '47,200', '130,000', '59,760', '405,000', '234,000', '45,600', '99,000', '216,000', '24,480', '52,920', '59,760', '180,000', '432,000', '40,095', '48,000', '33,048', '22,500', '60,000', '25,200', '49,896', '34,200', '61,740', '124,200', '28,800', '58,320', '106,920', '172,125', '395,000', '70,000', '48,000', '45,000', '96,000', '62,640', '215,000', '35,280', '35,100', '37,800', '88,776', '35,100', '35,280', '31,825', '49,320', '26,100', '226,800', '62,100', '232,200', '26,100', '48,000', '43,200', '54,720', '96,000', '82,800', '34,200', '69,000', '59,760', '27,900', '56,700', '30,960', '58,000', '54,000', '191,808', '65,880', '115,344', '48,000', '24,000', '96,000', '61,277', '56,700', '102,060']\n" ] } ], "source": [ "# 가격만 가져와 본다.\n", "my_prices = my_ul.select('div.opt_price em.ssg_price')\n", "my_prices_list =[x.text.strip() for x in my_prices]\n", "print(my_prices_list)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2. 가격 가져오기:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# 반복적인 부분은 함수로 처리한다.\n", "# select 메서드 사용.\n", "def get_prices(my_soup):\n", " my_names = my_ul.select('a em.tx_ko')\n", " my_names_list =[x.text.strip() for x in my_names]\n", " my_prices = my_ul.select('div.opt_price em.ssg_price')\n", " my_prices_list =[x.text.strip() for x in my_prices]\n", " my_prices_list_final= [float(''.join(a_price.split(','))) for a_price in my_prices_list]\n", " return pd.DataFrame({'Product':my_names_list, 'Price':my_prices_list_final})" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "for i in range(1,20):\n", " my_url_page = my_url + str(i)\n", " my_result = rq.get(my_url_page, headers=my_headers)\n", " if (my_result.status_code != 200):\n", " break\n", " my_html = my_result.content\n", " soup = bs4.BeautifulSoup(my_html, 'html.parser') # BeautifulSoup 객체 반환. 'html.parser' 사용.\n", " if i == 1:\n", " df = get_prices(soup)\n", " else:\n", " df = pd.concat([df, get_prices(soup)],axis=0,ignore_index=True)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(720, 2)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.shape" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", " | Product | \n", "Price | \n", "
---|---|---|
0 | \n", "(특별적립,공지확인필)화애락진 70ml*30포 (30일분) | \n", "144000.0 | \n", "
1 | \n", "(특별적립,공지확인필)황진단 4g*12환 (12일분) | \n", "216000.0 | \n", "
2 | \n", "(특별적립,공지확인필)화애락후 70ml*30포 (30일분) | \n", "180000.0 | \n", "
3 | \n", "(특별적립,공지확인필)굿베이스 홍삼담은 석류 (50ml*30포) | \n", "42400.0 | \n", "
4 | \n", "(특별적립,공지확인필)천녹정 180g*2병 (보자기포장) | \n", "405000.0 | \n", "
... | \n", "... | \n", "... | \n", "
715 | \n", "[1월22일 오후4시 주문건까지 명절전배송][센트룸] 여성 멀티비타민 포우먼 (50정) | \n", "24000.0 | \n", "
716 | \n", "[1월22일 오후4시 주문건까지 명절전배송][백화점선물포장][센트룸] 포맨 + 포우... | \n", "96000.0 | \n", "
717 | \n", "[1/22일 16시 명절배송마감]콤비타 UMF5+ 마누카꿀 500g | \n", "61277.0 | \n", "
718 | \n", "[1/22일 16시 명절배송마감]여성을위한멀티비타민미네랄x2팩 | \n", "56700.0 | \n", "
719 | \n", "[1/22일 16시 명절배송마감]수퍼바이오틱스/60캡슐x2팩 | \n", "102060.0 | \n", "
720 rows × 2 columns
\n", "