ch0nny_log

[빅데이터분석] Python_36. 파이썬 웹스크롤링8 (네이버 쇼핑) 본문

빅데이터 분석(with 아이티윌)/python

[빅데이터분석] Python_36. 파이썬 웹스크롤링8 (네이버 쇼핑)

chonny 2024. 8. 20. 16:29

◈ 네이버 쇼핑 웹 스크롤링

※ 네이버 블로그 웹스크롤링 실습

1. 네이버 쇼 상세 url 함수 만들기
import urllib.request    # 웹요청 모듈 
from bs4 import BeautifulSoup    # html 파싱 모듈 
from selenium import webdriver   # 브라우저 제어 모듈 
from selenium.webdriver.chrome.service import Service   # 드라이버 관리 모듈 
from selenium.webdriver.common.by import By     # 요소 탐색 모듈 
import time    # 대기 시간 정해주는 모듈
from selenium.webdriver.chrome.options import Options

def  naver_shopping(keyword, num):
    
    # 크롬 로봇 드라이버의 위치를 지정
    chrome_options =  Options()
    service = Service("C:\\data\\chromedriver-win32\\chromedriver-win32\\chromedriver.exe")
    driver2 = webdriver.Chrome(service=service, options=chrome_options)

    #검색 키워드 입력
    text1 = urllib.parse.quote(keyword)

    # 데이터를 수집할 리스트 선언
    list_name = []   #  상품명
    list_price = []  #  상품가격
    list_date = []   # 등록일 

    # 페이지 번호로 해당 html 코드 가져오기 
    for  i   in  range(1,num+1):
        url ="https://search.shopping.naver.com/search/all?adQuery=" + text1 + "origQuery=" + text1 + "&pagingIndex=" + str(i) + "&pagingSize=40&productSet=total&query=" + text1 + "&sort=rel&timestamp=&viewType=list"


2. 네이버 쇼핑 리스트 자동 스크롤
        # 크롬 로봇이 웹페이지를 열게합니다.
        driver2.get(url)
        time.sleep(2)

        # 크롬 로봇에 마우스 스크롤을 아래로 내려서 전체 페이지가 다 보이게 합니다.
        for  i  in  range(1,6):
            driver2.find_element(By.XPATH, value='//body').send_keys(Keys.END)
            time.sleep(2)

        # 보이는 웹페이지의 html 코드를 뷰티플 스프로 파싱합니다. 
        soup = BeautifulSoup(driver2.page_source, 'html.parser')


3. 상품 정보가 있는 html 코드 부분으로 접근

  # 상품 정보가 있는 html 코드 부분으로 접근
        goods_list = soup.select('div.adProduct_item__1zC9h')​

4. 상품명, 가격, 등록일을 리스트에 각각 담아내기
     # 상품명, 가격, 등록일을 리스트에 각각 담아냄 
        for  i  in   goods_list:
            #상품명 
            print( i.select_one('div.adProduct_title__amInq > a').get('title') )
            #상품가격
            print( i.select_one('span.price_num__S2p_v').text )     
            # 배송비
            print( i.select_one('span.price_delivery__yw_We').text )


★ 총코드
import urllib.request    # 웹요청 모듈 
from bs4 import BeautifulSoup    # html 파싱 모듈 
from selenium import webdriver   # 브라우저 제어 모듈 
from selenium.webdriver.chrome.service import Service   # 드라이버 관리 모듈 
from selenium.webdriver.common.by import By     # 요소 탐색 모듈 
from selenium.webdriver.common.keys import Keys
import time    # 대기 시간 정해주는 모듈
from selenium.webdriver.chrome.options import Options


def  naver_shopping(keyword, num):
    
    # 크롬 로봇 드라이버의 위치를 지정
    chrome_options =  Options()
    service = Service("C:\\data\\chromedriver-win32\\chromedriver-win32\\chromedriver.exe")
    driver2 = webdriver.Chrome(service=service, options=chrome_options)

    #검색 키워드 입력
    text1 = urllib.parse.quote(keyword)

    # 데이터를 수집할 리스트 선언
    list_name = []   #  상품명
    list_price = []  #  상품가격
    list_date = []   # 등록일 

    # 페이지 번호로 해당 html 코드 가져오기 
    for  i   in  range(1,num+1):
        url ="https://search.shopping.naver.com/search/all?adQuery=" + text1 + "origQuery=" + text1 + "&pagingIndex=" + str(i) + "&pagingSize=40&productSet=total&query=" + text1 + "&sort=rel&timestamp=&viewType=list"

        # 크롬 로봇이 웹페이지를 열게합니다.
        driver2.get(url)
        time.sleep(2)

        # 크롬 로봇에 마우스 스크롤을 아래로 내려서 전체 페이지가 다 보이게 합니다.
        for  i  in  range(1,6):
            driver2.find_element(By.XPATH, value='//body').send_keys(Keys.END)
            time.sleep(2)

        # 보이는 웹페이지의 html 코드를 뷰티플 스프로 파싱합니다. 
        soup = BeautifulSoup(driver2.page_source, 'html.parser')

        # 상품 정보가 있는 html 코드 부분으로 접근
        goods_list = soup.select('div.adProduct_item__1zC9h')

        # 상품명, 가격, 등록일을 리스트에 각각 담아냄 
        for  i  in   goods_list:
            #상품명 
            print( i.select_one('div.adProduct_title__amInq > a').get('title') )
            #상품가격
            print( i.select_one('span.price_num__S2p_v').text )     
            # 배송비
            print( i.select_one('span.price_delivery__yw_We').text )


naver_shopping('선풍기', 1)​

 


+ 추가 (20240821)

광고 아이템 기준 코드 가져오기

import urllib.request    # 웹요청 모듈 
from bs4 import BeautifulSoup    # html 파싱 모듈 
from selenium import webdriver   # 브라우저 제어 모듈 
from selenium.webdriver.chrome.service import Service   # 드라이버 관리 모듈 
from selenium.webdriver.common.by import By     # 요소 탐색 모듈 
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
import time    # 대기 시간 정해주는 모듈 

def naver_shopping(keyword, n):


    # 크롬 로봇 드라이버의 위치를 지정
    chrome_options =  Options()
    service = Service('C:\\data\\chromedriver-win32\\chromedriver-win32\\chromedriver.exe')
    driver = webdriver.Chrome(service=service, options=chrome_options)

    text1 = urllib.parse.quote(keyword)

    list_name = []   #  상품명
    list_price = []  #  상품가격
    list_date = []   # 등록일 

    
    params = []

    for i in range(1,1+n):
        list_url = f'https://search.shopping.naver.com/search/all?adQuery={text1}&origQuery={text1}&pagingIndex={i}&pagingSize=40&productSet=total&query={text1}&sort=rel&timestamp=&viewType=list'
        
        # 크롬 로봇에 웹페이지를 엽니다.
        driver.get(list_url)

        # 크롬 로봇에 마우스 스크롤을 아래로 내려서 전체 페이지가 다 보이게 합니다.
        for  i  in  range(1,6):
            driver.find_element(By.XPATH, value='//body').send_keys(Keys.END)
            time.sleep(0.5)

        # 보이는 웹페이지의 html 코드를 뷰티플 스프로 파싱합니다. 
        time.sleep(2) # 웹페이지가 다 뜰 수 있도록 기다려줌 

        # 현재 페이지를 BS 로 파싱
        soup = BeautifulSoup(driver.page_source, 'html.parser')

        # 광고 상품 정보가 있는 html 코드 부분으로 접근
        goods_list = soup.select('div.adProduct_item__1zC9h') # 상품명
        price_list = soup.select('span.price_num__S2p_v')  # 가격
        reg_list = soup.select('div.adProduct_etc_box__UJJ90') # 등록일
        
        # 상품명, 가격, 등록일을 리스트에 각각 담아냄 
        for  i,m,n  in  zip( goods_list, price_list, reg_list):
            price_text = m.text.strip()
            reg_list = n.text.strip()
            #상품명 
            print( i.select_one('div.adProduct_title__amInq > a').get('title'), price_text,reg_list)

naver_shopping('그릭 요거트', 1)

 

※ 광고가 아닌 상품 정보도 가져오기

import urllib.request    # 웹요청 모듈 
from bs4 import BeautifulSoup    # html 파싱 모듈 
from selenium import webdriver   # 브라우저 제어 모듈 
from selenium.webdriver.chrome.service import Service   # 드라이버 관리 모듈 
from selenium.webdriver.common.by import By     # 요소 탐색 모듈 
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
import time    # 대기 시간 정해주는 모듈 

def naver_shopping(keyword, n):


    # 크롬 로봇 드라이버의 위치를 지정
    chrome_options =  Options()
    service = Service('C:\\data\\chromedriver-win32\\chromedriver-win32\\chromedriver.exe')
    driver = webdriver.Chrome(service=service, options=chrome_options)

    text1 = urllib.parse.quote(keyword)

    list_name = []   #  상품명
    list_price = []  #  상품가격
    list_date = []   # 등록일 

    
    params = []

    for i in range(1,1+n):
        list_url = f'https://search.shopping.naver.com/search/all?adQuery={text1}&origQuery={text1}&pagingIndex={i}&pagingSize=40&productSet=total&query={text1}&sort=rel&timestamp=&viewType=list'
        
        # 크롬 로봇에 웹페이지를 엽니다.
        driver.get(list_url)

        # 크롬 로봇에 마우스 스크롤을 아래로 내려서 전체 페이지가 다 보이게 합니다.
        for  i  in  range(1,6):
            driver.find_element(By.XPATH, value='//body').send_keys(Keys.END)
            time.sleep(0.5)

        # 보이는 웹페이지의 html 코드를 뷰티플 스프로 파싱합니다. 
        time.sleep(2) # 웹페이지가 다 뜰 수 있도록 기다려줌 

        # 현재 페이지를 BS 로 파싱
        soup = BeautifulSoup(driver.page_source, 'html.parser')

        # 광고 상품 정보가 있는 html 코드 부분으로 접근
        goods_list = soup.select('div.adProduct_item__1zC9h') # 상품명
        price_list = soup.select('span.price_num__S2p_v')  # 가격
        reg_list = soup.select('div.adProduct_etc_box__UJJ90') # 등록일
        
        # 상품명, 가격, 등록일을 리스트에 각각 담아냄 
        for  g,p,r  in  zip( goods_list, price_list, reg_list):
            price_text = p.text.strip()
            reg_list = r.text.strip()
            #상품명 
            print( g.select_one('div.adProduct_title__amInq > a').get('title'), price_text,reg_list)
            print( '-' * 80 )
            
        # 광고가 아닌 상품 정보가 있는 html 코드 부분으로 접근
        goods_list = soup.select('div.product_item__MDtDF') # 상품명

        # for  i  in  goods_list:
        #     print( i.select_one('div.product_title__Mmw2K > a').get('title') )
            
        price_list = soup.select('span.price_num__S2p_v')  # 가격

        reg_list = soup.select('div.product_etc_box__ElfVA') # 등록일
        
        # 광고가 아닌 상품명, 가격, 등록일을 리스트에 각각 담아냄 
        for  g,p,r  in  zip( goods_list, price_list, reg_list):
            price_text = p.text.strip()
            reg_list = r.text.strip()
            #상품명 
            print( g.select_one('div.product_title__Mmw2K > a').get('title'), price_text,reg_list)
            print( '-' * 80 )

naver_shopping('그릭 요거트', 1)

 

※ 네이버 쇼핑 스크롤링 코드를 데이터가 저장될 수 있는 코드로 수정하기

#14. 네이버 쇼핑 데이터 수집


import urllib.request    # 웹요청 모듈 
from bs4 import BeautifulSoup    # html 파싱 모듈 
from selenium import webdriver   # 브라우저 제어 모듈 
from selenium.webdriver.chrome.service import Service   # 드라이버 관리 모듈 
from selenium.webdriver.common.by import By     # 요소 탐색 모듈 
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
import time    # 대기 시간 정해주는 모듈 


import urllib.request    # 웹요청 모듈 
from bs4 import BeautifulSoup    # html 파싱 모듈 
from selenium import webdriver   # 브라우저 제어 모듈 
from selenium.webdriver.chrome.service import Service   # 드라이버 관리 모듈 
from selenium.webdriver.common.by import By     # 요소 탐색 모듈 
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
import time    # 대기 시간 정해주는 모듈 

def n_shopping(keyword, n):


    # 크롬 로봇 드라이버의 위치를 지정
    chrome_options =  Options()
    service = Service('C:\\data\\chromedriver-win32\\chromedriver-win32\\chromedriver.exe')
    driver = webdriver.Chrome(service=service, options=chrome_options)

    text1 = urllib.parse.quote(keyword)

    list_name = []   #  상품명
    list_price = []  #  상품가격
    list_date = []   # 등록일 

    
    params = []

    for i in range(1,1+n):
        list_url = f'https://search.shopping.naver.com/search/all?adQuery={text1}&origQuery={text1}&pagingIndex={i}&pagingSize=40&productSet=total&query={text1}&sort=rel&timestamp=&viewType=list'
        
        # 크롬 로봇에 웹페이지를 엽니다.
        driver.get(list_url)

        # 크롬 로봇에 마우스 스크롤을 아래로 내려서 전체 페이지가 다 보이게 합니다.
        for  i  in  range(1,6):
            driver.find_element(By.XPATH, value='//body').send_keys(Keys.END)
            time.sleep(0.5)

        # 보이는 웹페이지의 html 코드를 뷰티플 스프로 파싱합니다. 
        time.sleep(2) # 웹페이지가 다 뜰 수 있도록 기다려줌 

        # 현재 페이지를 BS 로 파싱
        soup = BeautifulSoup(driver.page_source, 'html.parser')

        # 광고 상품 정보가 있는 html 코드 부분으로 접근
        goods_list = soup.select('div.adProduct_item__1zC9h') # 상품명
        price_list = soup.select('strong.adProduct_price__9gODs > span.price > span.price_num__S2p_v > em')  # 가격
        reg_list = soup.select('div.adProduct_etc_box__UJJ90') # 등록일
        
        # 상품명, 가격, 등록일을 리스트에 각각 담아냄 
        for  g,p,r  in  zip( goods_list, price_list, reg_list):
            price_text = p.text.strip()
            reg_list = r.text.strip().lstrip('리뷰,별점,만,천,백,십,일,구매,(,),1,2,3,4,5,6,7,8,9,0,.,,,찜').rstrip('.정보,신고하기,톡톡,수정요청').rstrip('.정보 ')
            #상품명 
            print( g.select_one('div.adProduct_title__amInq > a').get('title'), price_text,reg_list)
            print( '-' * 80 )
            
        # 광고가 아닌 상품 정보가 있는 html 코드 부분으로 접근
        goods_list = soup.select('div.product_item__MDtDF') # 상품명
        price_list = soup.select('strong.product_price__52oO9 > span.price > span.price_num__S2p_v > em')  # 가격
        reg_list = soup.select('div.product_etc_box__ElfVA') # 등록일
        
        # 광고가 아닌 상품명, 가격, 등록일을 리스트에 각각 담아냄 
        for  g,p,r  in  zip( goods_list, price_list, reg_list):
            price_text = p.text.strip()
            reg_list = r.text.strip().lstrip('리뷰,별점,만,천,백,십,일,구매,(,),1,2,3,4,5,6,7,8,9,0,.,,,찜').rstrip('.정보,신고하기,톡톡,수정요청').rstrip('.정보 ')
            #상품명 
            print( g.select_one('div.product_title__Mmw2K > a').get('title'), price_text,reg_list)
            print( '-' * 80 )

#n_shopping('그릭 요거트', 1)

+ 추가 (20240822)

※ 네이버 쇼핑 스크롤링 코드를 파일로 저장

# pip install webdriver-manager
import urllib.request    # 웹요청 모듈 
from bs4 import BeautifulSoup    # html 파싱 모듈 
from selenium import webdriver   # 브라우저 제어 모듈 
from selenium.webdriver.chrome.service import Service   # 드라이버 관리 모듈 
from selenium.webdriver.common.by import By     # 요소 탐색 모듈 
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
import time    # 대기 시간 정해주는 모듈 
from webdriver_manager.chrome import ChromeDriverManager

def naver_shopping(keyword, n):

    # 크롬 로봇 드라이버의 위치를 지정
    chrome_options =  Options()
    # service = Service('C:\\data\\chromedriver-win32\\chromedriver-win32\\chromedriver.exe')
    # driver = webdriver.Chrome(service=service, options=chrome_options)
    service = Service(ChromeDriverManager().install())
    driver = webdriver.Chrome(service=service, options=chrome_options)

    text1 = urllib.parse.quote(keyword)

    list_name = []   #  상품명
    list_price = []  #  상품가격
    list_date = []   # 등록일 

    for i in range(1,1+n):
        list_url = f'https://search.shopping.naver.com/search/all?adQuery={text1}&origQuery={text1}&pagingIndex={i}&pagingSize=40&productSet=total&query={text1}&sort=rel&timestamp=&viewType=list'
        
        # 크롬 로봇에 웹페이지를 엽니다.
        driver.get(list_url)

        # 크롬 로봇에 마우스 스크롤을 아래로 내려서 전체 페이지가 다 보이게 합니다.
        for  i  in  range(1,6):
            driver.find_element(By.XPATH, value='//body').send_keys(Keys.END)
            time.sleep(0.5)

        # 보이는 웹페이지의 html 코드를 뷰티플 스프로 파싱합니다. 
        time.sleep(2) # 웹페이지가 다 뜰 수 있도록 기다려줌 

        # 현재 페이지를 BS 로 파싱
        soup = BeautifulSoup(driver.page_source, 'html.parser')

        # 광고 상품 정보가 있는 html 코드 부분으로 접근
        goods_list = soup.select('div.adProduct_item__1zC9h') # 상품명
        price_list = soup.select('strong.adProduct_price__9gODs > span.price > span.price_num__S2p_v > em')  # 가격
        reg_list = soup.select('div.adProduct_etc_box__UJJ90') # 등록일
        
        # 상품명, 가격, 등록일을 리스트에 각각 담아냄 
        for  g,p,r  in  zip( goods_list, price_list, reg_list):
            #price_text = p.text.strip()
            reg_list = r.text.strip().lstrip('리뷰,별점,만,천,백,십,일,구매,(,),1,2,3,4,5,6,7,8,9,0,.,,,찜').rstrip('.정보,신고하기,톡톡,수정요청').rstrip('.정보 ')
            #상품명 
            #print( g.select_one('div.adProduct_title__amInq > a').get('title'), price_text,reg_list)
            #print( '-' * 80 )
            
        # 광고가 아닌 상품 정보가 있는 html 코드 부분으로 접근
        goods_list = soup.select('div.product_item__MDtDF') # 상품명
        price_list = soup.select('strong.product_price__52oO9 > span.price > span.price_num__S2p_v > em')  # 가격
        reg_list = soup.select('div.product_etc_box__ElfVA') # 등록일
        
        # 광고가 아닌 상품명, 가격, 등록일을 리스트에 각각 담아냄 
        for  g,p,r  in  zip( goods_list, price_list, reg_list):
            product_name = g.select_one('div.product_title__Mmw2K > a').get('title')
            price_text = p.text.strip()
            reg_list = r.text.strip().lstrip('리뷰,별점,만,천,백,십,일,구매,(,),1,2,3,4,5,6,7,8,9,0,.,,,찜').rstrip('.정보,신고하기,톡톡,수정요청').rstrip('.정보 ')
            reg_list = reg_list[4: ]            

            #리스트에 추가하기 
            list_name.append(product_name)
            list_price.append(price_text)
            list_date.append(reg_list)

    #pandas 데이터 프레임 생성
    df = pd.DataFrame( { '상품명' : list_name,
                         '가격'   : list_price,
                         '등록일' : list_date 
                       } )

    #csv 파일로 저장 
    df.to_csv("c:\\data\\naver_shopping.csv", encoding="utf8", index=False)
    print('성공적으로 c:\\data\\naver_shopping.csv 가 저장되었습니다')
            
naver_shopping('그릭 요거트', 2)

 

 

문제1. 네이버  쇼핑에서 '그릭 요거트'  로 검색한 데이터를 판다스 데이터 프레임으로 생성하고 출력하시오.
import pandas as pd

nv_greek =  pd.read_csv('c:\\data\\naver_shopping.csv')


nv_greek['가격'] = nv_greek['가격'].str.replace(r'[^\d]','',regex=True).astype('int64')
nv_greek.info()​


문제2. padsaql을 이용해서 nv_greek 데이터 프레임을 셀렉트 하시오.

import pandas as pd
from pandasql import sqldf

nv_greek = pd.read_csv("c:\\data\\naver_shopping.csv")
nv_greek['가격'] = nv_greek['가격'].str.replace(r'[^\d]','',regex=True).astype('int64')

pysqldf = lambda q : sqldf(q,globals())

q = """ select *
               from nv_greek ;"""

pysqldf(q)

 


문제 3. c 드라이브 밑에 cuppang_shopping.csv 를 불러와서 위와 같이 구성하시오.

import pandas as pd
from pandasql import sqldf

cp_greek = pd.read_csv("c:\\data\\cuppang_shopping.csv")
cp_greek['가격'] = cp_greek['가격'].str.replace(r'[^\d]','',regex=True).astype('int64')

pysqldf = lambda q : sqldf(q,globals())

q = """ select *
               from cp_greek ;"""

pysqldf(q)

 


문제 4. 쿠팡과 네이버의 검색결과를 서로 조인하시오. (공통된 컬럼이 나오게) _ cross join
q = """ 
select c.상품명, c.가격, n.상품명, n.가격
    from cp_greek c  cross join nv_greek n; 
    """


pysqldf(q)​

설명: 공통된 컬럼이 없어서 다 join 된 것

문제5. 쿠팡 테이블에서 '일동 후디스'를 포함하는 상품명과 가격을 출력하고, 그 아래에 네이버에서 '일동 후디스'를 포함하는 상품명과 가격을 출력하시오. 이때 두 결과는 UNION ALL을 사용하여 결합하시오.

q = """ 
select 'cupang' as col1 , 상품명, 가격
    from cp_greek
    where 상품명 like '%일동후디스%'
  
  union all

select 'naver'as col1 , 상품명, 가격
    from nv_greek
    where 상품명 like '%일동후디스%';"""


pysqldf(q)

 



문제 6. 다른상품으로 위와 같이 가격 비교를 하시오.

 

※ 조인문법
1. 오라클 조인문법 1. equi join
2. non equi join
3. outer join
4. self join
2. 1999 ansi 조인문법 1. on 절을 사용한 조인
2. using 절을 사용한 조인
3. left/right/full outer 조인
4. cross 조인
★ 마지막 문제. 다른상품으로 위와 같이 가격 비교를 하시오.

1. 쿠팡과 네이버 쇼핑 웹 크롤링 (키워드: 우산)
import chj

chj.naver_shopping('우산', 2)
chj.get_coupang_data('우산', 2)​


2. 데이터 프레임 생성

# 쿠팡
import pandas as pd
from pandasql import sqldf

cp_umbrella = pd.read_csv("c:\\data\\cuppang_shopping.csv")
cp_umbrella['가격'] = cp_umbrella['가격'].str.replace(r'[^\d]','',regex=True).astype('int64')

pysqldf = lambda q : sqldf(q,globals())

q = """ select *
               from cp_umbrella ;"""

pysqldf(q)
# 네이버
import pandas as pd
from pandasql import sqldf

nv_umbrella = pd.read_csv("c:\\data\\naver_shopping.csv")
nv_umbrella['가격'] = nv_umbrella['가격'].str.replace(r'[^\d]','',regex=True).astype('int64')

pysqldf = lambda q : sqldf(q,globals())

q = """ select *
               from nv_umbrella ;"""

pysqldf(q)


3. "3단" 이 들어간 상품명 중 10000원 이하 가격비교 후 가격이 낮은 순서대로 순위 컬럼 추가하기 

from pandasql import sqldf

q = """
WITH combined_data AS (
    SELECT 'cupang' AS col1, 상품명, 가격
    FROM cp_umbrella
    WHERE 상품명 LIKE '%3단%' AND 가격 <= 10000

    UNION ALL

    SELECT 'naver' AS col1, 상품명, 가격
    FROM nv_umbrella
    WHERE 상품명 LIKE '%3단%' AND 가격 <= 10000
)

SELECT col1, 상품명, 가격,
       ROW_NUMBER() OVER (ORDER BY 가격) AS 순위
FROM combined_data;
"""

pysqldf(q)