Selenium 실습

이상해씨·2021년 10월 11일
0

EDA, 웹크롤링

목록 보기
11/13

◾import

import numpy as np
import pandas as pd
import requests
import time
import tqdm
import warnings

from bs4 import BeautifulSoup
from selenium import webdriver
from tqdm import notebook

# expicitly wait를 위해 import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
# expicitly wait를 위해 import

warnings.simplefilter(action="ignore", category=FutureWarning)

◾iframe

  • iframe : html 안의 또 다른 html
    • selenium 활용
    • request 활용
  • 네이버 금융 추출 테스트
# 네이버 금융 접속
url = 'https://finance.naver.com/marketindex/'
driver = webdriver.Chrome('../driver/chromedriver.exe')
driver.get(url)

# 환전 고시 환율
contents = driver.find_elements_by_css_selector('#exchangeList > li > a')
print(contents[0].find_element_by_css_selector(".value").text)

# 주요 뉴스
news = driver.find_elements_by_css_selector('''#content > div.section_news > div > ul > li > p > a''')
print(news[0].text)

# 매매 기준율
# 실패 => 페이지 태그에 `iframe` 확인
tradings = driver.find_elements_by_css_selector('body > div > table > tbody > tr')
print(tradings)
  • 매매 기준율은 iframe에 담겨있어 바로 접근이 불가능하다.

1. Selenium

  • iframe 태그 지정 -> switch_to로 iframe으로 프레임 이동 -> 데이터 추출
# iframe 태그 지정
iframe = driver.find_element_by_id('frame_ex1')

# iframe 태그 이동
driver.switch_to_frame(iframe)
# 경고가 보기 싫다면 아래 사용
# driver.switch_to.frame(iframe)

# 매매 기준율 재시도
print(driver.find_element_by_class_name('sale').text)

# 매매 기준율 테이블 추출
tradings = driver.find_elements_by_css_selector('body > div > table > tbody > tr')
print(tradings[0].text)
print(tradings[0].find_element_by_css_selector(".tit").text)
print(tradings[0].find_element_by_css_selector(".sale").text)
print(tradings[0].find_elements_by_css_selector("td")[2].text)
print(tradings[0].find_elements_by_css_selector("td")[3].text)
print(tradings[0].find_elements_by_css_selector("td")[4].text)
print(tradings[0].find_elements_by_css_selector("td")[5].text)
print(tradings[0].find_elements_by_css_selector("td")[6].text)

2. Requests

  • 개발자 도구의 network에서 원하는 iframe 주소를 찾아 접근
# Requests 사용 : 접근 확인
url = 'https://finance.naver.com/marketindex/exchangeList.naver'
response = requests.get(url)
print(response)	# 상태 코드 확인

# 내용 확인
# response.text
print(response.content)

# 뷰티풀수프로 접근
soup = BeautifulSoup(response.content, 'html.parser')
print(soup.prettify())

# 테스트
print(soup.select_one('.sale').text)

◾handless

  • 셀레니움시 화면에 보여야 작동하는 경우가 있기 때문에 최대화, 스크롤 이동 등을 진행
  • 웹 브라우저가 없는 경우 또는 웹브라우저 실행없이 동작 :_____Options() 사용
# 웹 브라우저 실행되지 않도록 headless 사용
# options = webdriver.ChromeOptions()
# options.add_argument("headless")
# driver = webdriver.Chrome('../driver/chromedriver.exe', options = options)

# 네이버 금융
url = 'https://finance.naver.com/marketindex/'
driver = webdriver.Chrome('../driver/chromedriver.exe')
driver.get(url)
# 화면에 보여야 작동하는 경우도 있기 때문에 최대 크기로 조절
# driver.set_window_size(1920, 1000)
driver.maximize_window()
time.sleep(3)

# 화면 스크롤 하단 이동
driver.execute_script('window.scrollTo(0, document.body.scrollHeight);')

# iframe 태그 지정
iframe = driver.find_element_by_id('frame_ex1')

# iframe 태그 이동
driver.switch_to_frame(iframe)
time.sleep(3)

tradings = driver.find_elements_by_css_selector('body > div > table > tbody > tr')
time.sleep(2)

# 데이터 추출
datas = []

for trading in tradings[:3]:
    title = trading.find_element_by_css_selector('.tit > a').text
    sale = trading.find_element_by_css_selector('.sale').text
    link = trading.find_element_by_css_selector('.tit > a').get_attribute('href')
    datas.append({
        'title' : title,
        'sale' : sale,
        'link' : link
    })
    # 정지를 당하지 않기 위해 sleep 사용
    time.sleep(3)

# driver.close()
driver.quit()

df = pd.DataFrame(datas)
print(df)

◾wait

  • wait : 페이지 로딩을 기다리고 로딩이 완료되면 바로 다음 코드 실행
    • time.sleep(10) : 물리적으로 10초동안 멈추어 기다림
    • implicityly_wait(10) : 전체 페이지 로딩을 10초동안 기다리고, 10초 안에 페이지 로딩이 완료되면 다음 코드 실행
      • 전역(global)으로 실행이 가능해 한 번만 실행한다.
    • explicitly_wait : 지정한 태그만 로딩이 완료되면, 다음 코드 실행
  • 무신사 스토어
    • https://store.musinsa.com/app/
    • 인기 -> 후드 집업
    • 단독상품, 세일상품 조건 선택
    • 최소 ~ 최대 금액 입력
    • 옷 이름, 가격, 할인율, 링크, 이미지
# expicitly wait를 위해 import
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
  • 무신사 스토어 접속
# 무신사 접속
url = 'https://store.musinsa.com/app/'
driver = webdriver.Chrome('../driver/chromedriver.exe')
driver.implicitly_wait(10)  # 웹 페이지 로딩 최대 10초 대기
driver.get(url)
  • 로그인 테스트
# 로그인 버튼 클릭
driver.find_element_by_css_selector('#default_top > div.header-member > button').click()

# 아이디, 비밀번호 입력, 로그인 버튼
# 없는 아이디, 비밀번호
# 경고창(alert) 발생
driver.find_element_by_css_selector('body > div.musinsa-wrapper.wrapper-member.devicePC > div > form > input:nth-child(2)').clear()
driver.find_element_by_css_selector('body > div.musinsa-wrapper.wrapper-member.devicePC > div > form > input:nth-child(2)').send_keys('test')
driver.find_element_by_css_selector('body > div.musinsa-wrapper.wrapper-member.devicePC > div > form > input:nth-child(3)').clear()
driver.find_element_by_css_selector('body > div.musinsa-wrapper.wrapper-member.devicePC > div > form > input:nth-child(3)').send_keys('test')
driver.find_element_by_css_selector('body > div.musinsa-wrapper.wrapper-member.devicePC > div > form > button').click()

# alert 처리
alert = driver.switch_to.alert
alert.accept()
  • expicitly wait 테스트
 로그인 버튼 부분을 최대 5초동안 기다리며 로딩이 되면 클릭
WebDriverWait(driver, 5).\
until(EC.presence_of_element_located((By.CSS_SELECTOR, "#default_top > div.header-member > button"))).click()

# 아이디 패스워드 입력
WebDriverWait(driver, 5).\
until(EC.presence_of_element_located((By.CSS_SELECTOR, "body > div.musinsa-wrapper.wrapper-member.devicePC > div > form > input:nth-child(2)"))).send_keys('test')
WebDriverWait(driver, 5).\
until(EC.presence_of_element_located((By.CSS_SELECTOR, "body > div.musinsa-wrapper.wrapper-member.devicePC > div > form > input:nth-child(3)"))).send_keys('test')

# 로그인 버튼
WebDriverWait(driver, 5).\
until(EC.presence_of_element_located((By.CSS_SELECTOR, "body > div.musinsa-wrapper.wrapper-member.devicePC > div > form > button"))).click()
  • 후드 집업 탭 열기
# 인기 -> 후드 집업 새 탭으로 열기
driver.execute_script("window.open('{}');".format(best_link))

# 후드 집업 탭으로 프레임 이동
driver.switch_to.window(driver.window_handles[1])
  • 옵션 선택
# 단독 상품, 세일 상품 선택
WebDriverWait(driver, 5).\
until(EC.presence_of_element_located((By.CSS_SELECTOR, "#btn_exclusive"))).click()
WebDriverWait(driver, 5).\
until(EC.presence_of_element_located((By.CSS_SELECTOR, "#btn_sale"))).click()

# 최소 금액, 최대 금액 추가, 버튼 클릭
WebDriverWait(driver, 5).\
until(EC.presence_of_element_located((By.CSS_SELECTOR, "#minPrice"))).send_keys('10000')
WebDriverWait(driver, 5).\
until(EC.presence_of_element_located((By.CSS_SELECTOR, "#maxPrice"))).send_keys('100000')
WebDriverWait(driver, 5).\
until(EC.presence_of_element_located((By.CSS_SELECTOR, "#btn_price_search"))).click()
  • 상품의 부모 태그 확인
# 부모 태그
outers = driver.find_elements_by_css_selector('#searchList > li')
len(outers), outers[0].text
  • 각 상품 태그 테스트
# 옷 이름
print(outers[0].find_element_by_css_selector('p.list_info > a').get_attribute('title'))
# 옷 가격
print(outers[0].find_element_by_css_selector('p.price').text.split(' ')[1][:-1])
# 옷 할인율
print(outers[0].find_element_by_css_selector('.icon_new').text.split(' ')[1][:-1])
# 옷 세부 링크
print(outers[0].find_element_by_css_selector('p.list_info > a').get_attribute('href'))
# 옷 이미지
# 확인결과 src 태그는 화면에 보여야 제대로 활성화 된다.
# 따라서 data-original 태그를 사용
# print(outers[0].find_element_by_css_selector('div.list_img > a > img').get_attribute('src'))
print(outers[0].find_element_by_css_selector('div.list_img > a > img').get_attribute('data-original'))
  • 이미지 저장
# 이미지 저장 : requests 사용
res = requests.get(outers[0].find_element_by_css_selector('div.list_img > a > img').get_attribute('data-original'))
# 파일모드 wb 
with open('./musinsa/outer.png', 'wb') as f:
    f.write(res.content)
profile
후라이드 치킨

0개의 댓글