동적인 컨텐츠로부터 필요한 데이터를 추출하는 방법
selenium 앱, 모듈이 필요함
- 시스템에 selenium 모듈 설치
- selenium 앱(웹드라이버) 다운로드
- selenium 모듈을 사용하여 웹드라이버 제어
- 웹드라이버는 웹브라우저를 제어하여 사이트에 접근
- 코드를 사용하여 브라우저 화면의 버튼도 클릭 가능
- 웹페이지 가져오기(crowling), 웹페이지로부터 추출(scraping)
- selenium, BeautifulSoup 연동 가능
설치
C:/temp/chromedriver.exe
pip install selenium
사용
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service
driver = webdriver.Chrome(executable_path='C:/Temp/chromedriver') # 드라이버가 저장된 경로
driver.get('https://naver.com')
driver.implicitly_wait(1) # 모두 로드가 될 때까지 충분히(1초) 기다린다
문법
find_element(By.ID,'id') # 아이디
find_element(By.NAME, 'name') # name 속성
find_element(By.XPATH, 'xpath') # xpath
find_element(By.LINK_TEXT, 'link text') # 링크 텍스트
find_element(By.PARTIAL_LINK_TEXT, 'partial link text') # 부분적인 링크 텍스트
find_element(By.TAG_NAME, 'tag name') # 태그 이름, 한개
find_elements(By.TAG_NAME, 'tag name') # 태그 이름, 여러개
find_element(By.CLASS_NAME, 'class name') # 클래스 이름
find_element(By.CSS_SELECTOR, 'css selector') # CSS 선택자
CLASS_NAME
res = driver.find_element(By.CLASS_NAME,'login_msg')
type(res) # selenium.webdriver.remote.webelement.WebElement
res.text.strip() # '네이버를 더 안전하고 편리하게 이용하세요'
res.get_attribute('class').strip() # 'login_msg'
XPATH
특정 태그에 접근하기 위한 경로 표현법
사용
res = driver.find_element(By.XPATH,'//*[@id="account"]/p') # <selenium.webdriver.remote.webelement.WebElement (session="52e59ced3cf08d0b7c8b874eda71d998", element="967fc44d-6e6e-4749-8e13-5bbd43804c9e")>
res.text # '네이버를 더 안전하고 편리하게 이용하세요'
문법
'//*[@id="account"]/p' # //(상대경로)*(모든태그)[@id="account"](아이디가 'account')/(하위경로)p(p태그)
CSS_SELECTOR
driver.find_element(By.CSS_SELECTOR,'#account>p.login_msg').text # '네이버를 더 안전하고 편리하게 이용하세요'
Input Tag에 값 집어넣기
input.send_keys('python')
Button Tag 클릭하기
button.click()
사용
# 검색창에 'python'을 입력하고 검색버튼 클릭하기
driver.find_element(By.CSS_SELECTOR, '#query').send_keys('python')
driver.find_element(By.CSS_SELECTOR, '#search_btn').click()
실습
##
# selenium, BeautifulSoup 등을 사용하여 아래의 문제를 해결해보세요
# 자신의 메일 목록에서 2페이지 분량의 메일 송신자, 제목, 날짜 정보를
# 가져와서 csv 파일에 저장하기
def addCsv(url, list_csv):
driver.get(url)
mails = driver.find_elements(By.CSS_SELECTOR,'.mail_item')
for mail in mails:
mail_sender = mail.find_element(By.CSS_SELECTOR,'.mail_sender')
button_sender = mail_sender.find_element(By.CSS_SELECTOR,'.button_sender')
sender = button_sender.text.split('\n')[1]
title = mail.find_element(By.CSS_SELECTOR,'.mail_title_link>.text').text
date = mail.find_element(By.CSS_SELECTOR,'.mail_date_wrap').text
csv = {}
csv['sender'] = sender
csv['title'] = title
csv['date'] = date
list_csv.append(csv)
list_csv = list()
addCsv('https://mail.naver.com/v2/folders/0/all?page=1',list_csv)
addCsv('https://mail.naver.com/v2/folders/0/all?page=1',list_csv)
with open('mail_csv.csv','wt') as fout:
for csv in list_csv:
fout.write(f"{csv['sender']},{csv['title']},{csv['date']}\n")
##
##
# Spring 웹에서 [사원정보 보기] 버튼을 누르면 위의 사원정보가 json 문자열 형식
# 으로 응답되는 기능을 작성한다. 로그인한 이용자만 버튼을 누를 수 있게 한다
# 버튼을 누르면, gender, first_name, phone, job_title
# <table> 안에 표시되도록 한다
# Python 데이터 수집 시스템을 작성하여 화면에 표시된 사원정보 테이블에서
# 데이터를 읽어와서 python_emp_table.json 파일에 저장한다
# 파일에 저장된 사원정보는 언제든지 파이썬을 이용하여 화면에 표시될 수 있어야 한다.
import requests
res = requests.get('http://localhost/crawl/login?id=smith&pw=1111')
from selenium import webdriver
driver = webdriver.Chrome('C:/Temp/chromedriver');
driver.get('http://localhost/crawl/login?id=smith&pw=1111')
driver.implicitly_wait(1)
from selenium.webdriver.common.by import By
driver.find_element(By.CSS_SELECTOR,'#employees_btn').click()
driver.implicitly_wait(1)
employee_tr = driver.find_elements(By.CSS_SELECTOR,'.employee')
with open('employees.csv','wt') as fout:
for tr in employee_tr:
str_csv = f"{tr.find_element(By.CSS_SELECTOR,'.gender').text},{tr.find_element(By.CSS_SELECTOR,'.first_name').text},{tr.find_element(By.CSS_SELECTOR,'.phone').text},{tr.find_element(By.CSS_SELECTOR,'.job_title').text}\n"
fout.write(str_csv);
print(str_csv)
##