경기도미래기술학교 AI개발자 부트캠프 13일차 TIL - 크롤링, 네이버 OPEN API 하는법, 크롬 브라우저에서 Selenium을 했다.

2023. 5. 24. 19:42python

반응형
import requests
from bs4 import BeautifulSoup

html = driver.page_source #페이지소스를 html 변수에 넣음
soup = BeautifulSoup(html,'lxml') # html을 파싱

#content > div.style_content__xWg5l > div.basicList_list_basis__uNBZx > div > div:nth-child(1) > div > div > div.basicList_info_area__TWvzp > div.basicList_title__VfX3c > a
onetitle = soup.select_one('#content > div.style_content__xWg5l > div.basicList_list_basis__uNBZx > div > div:nth-child(1) > div > div > div.basicList_info_area__TWvzp > div.basicList_title__VfX3c > a')
title_list = soup.select('#content > div.style_content__xWg5l > div.basicList_list_basis__uNBZx > div > div')

# print(onetitle.text)
#content > div.style_content__xWg5l > div.basicList_list_basis__uNBZx > div > div:nth-child(7) > div > div > div.basicList_info_area__TWvzp > div.basicList_price_area__K7DDT > strong > span > span > span.price_num__S2p_v
price_list = soup.select('#content > div.style_content__xWg5l > div.basicList_list_basis__uNBZx > div > div')

titles=[]
prices=[]

for title in title_list:
#     print(title.select_one('div > div > div.basicList_info_area__TWvzp > div.basicList_title__VfX3c > a').text)
#     print(title.select_one('div > div > div.basicList_info_area__TWvzp > div.basicList_price_area__K7DDT > strong > span > span > span.price_num__S2p_v').text)
    titles.append(title.select_one('div > div > div.basicList_info_area__TWvzp > div.basicList_title__VfX3c > a').text)
    try:
        prices.append(title.select_one('div > div > div.basicList_info_area__TWvzp > div.basicList_price_area__K7DDT > strong > span > span > span.price_num__S2p_v').text)
    except:
        prices.append('판매중단')
    
import pandas as pd

data={"세탁기명":titles,"가격":prices}
W_M=pd.DataFrame(data)
display(W_M)

copy selector를 통한 크롤링을 했다. 아니 근데 이거 mac으로 하면 잘 안된다. 이것 때문에 항상 오래 걸린다. mac이 문제다 참. 아무튼 엑셀 저장까지는 아니고 display를 통해 확인 후 마무리했다.

 

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import StaleElementReferenceException
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.action_chains import ActionChains

import time
from bs4 import BeautifulSoup
import pandas as pd

def scroll():
    first_h = driver.execute_script("return window.scrollY")#현재의 스크롤높이

    if first_h !=0:
        driver.execute_script("return window.scrollTo(0,0)")#현재의 스크롤높이

    while True:
        driver.find_element(By.CSS_SELECTOR,'body').send_keys(Keys.PAGE_DOWN)

        time.sleep(0.5)
        #새로운 높이

        new_h = driver.execute_script("return window.scrollY")

        if first_h == new_h :
            break
        else:
            first_h=new_h

url = 'https://www.gmarket.co.kr/n/best?viewType=G&groupCode=G10'
driver = webdriver.Chrome(ChromeDriverManager().install())
driver.get(url)

img_elements = driver.find_elements(By.CSS_SELECTOR,'img.image__lazy.image__load')

html = driver.page_source #페이지소스를 html 변수에 넣음
soup = BeautifulSoup(html,'lxml') # html을 파싱

scroll()

title = []
price = []
category = []

while True:
    new_img_elements = driver.find_elements(By.CSS_SELECTOR,'img.image__lazy.image__load')
   
    for i in range(len(title), len(new_img_elements)):
        
        scroll()
        
        imgs = new_img_elements[i]

        # 이미지 클릭
        try:
            imgs.click()
        except StaleElementReferenceException:
            # 이미지 요소가 변경되어 클릭할 수 없는 경우, 다시 해당 요소를 찾아서 클릭
            imgs = driver.find_elements(By.CSS_SELECTOR,'img.image__lazy.image__load')[i]
            imgs.click()

        # 본문 내용 크롤링
        html = driver.page_source
        soup = BeautifulSoup(html, 'lxml')
        try:
            title.append(soup.select_one('#itemcase_basic > div > h1').text)
        except:
            title.append('없는 목록')
        try:
            price.append(soup.select_one('#itemcase_basic > div > div.price > span.price_innerwrap > strong').text)
        except:
            price.append('없는 목록')
        try:
            category.append(soup.select_one('body > div.location-navi > ul > li.on > a').text)
        except:
            category.append('없는 목록')

        # 이전 페이지로 돌아가기
        driver.back()

    time.sleep(2)

    if len(new_img_elements) == len(img_elements):
        break
        
data={"책이름":title,"가격":price,"카테고리":category}
book_list=pd.DataFrame(data)
display(book_list)

 

많은 일화가 있었다,.. 이게 자꾸 out of range 오류가 나거나 DOM에서 소스를 찾을 수 없는 오류가 발생한다.

range(len(title), len(new~~)라는 것은 ~부터 ~까지 라는 것이다. 그래서 len(title)을 쓰면 전에 등록된 것은 제외되고 새 것부터 루프가 돈다. 그렇게 100번씩 돌고 for문을 빠져나오면 while에 break는 원래부터 숫자가 같았기 때문에 while문을 빠져나오며 디스플레이가 보인다.

 

 

728x90