728x90
반응형
Selenium(셀레니움)
- 웹 브라우저의 자동화를 가능하게 하고 지원하는 다양한 도구와 라이브러리를 포함한 프로젝트
- 웹 앱을 테스트 할 때 주로 사용하는 프레임워크
- webdriver라는 api를 통해서 browser 제어
- 동적인 환경에서 크롤링
- 웹 테스트의 자동화
www.selenium.dev/documentation/ko/
Selenium 라이브러리 설치
pip install selenium
browser driver 설치
- Chrome : https://chromedriver.chromium.org/downloads
- Edge : https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
- Firefox : https://github.com/mozilla/geckodriver/releases
- Safari : https://webkit.org/blog/6900/webdriver-support-in-safari-10/
Linux OS의 경우 다음 명령어로 chrome driver 설치 가능
apt install chromium-chromedriver
Selenium 요소 및 함수
Waits
- selenium을 사용해 테스트 할 때 elements를 찾을 수 있도록 web page가 로딩이 끝날 때 까지 기다려야 함.
- AJAX를 이용해 만든 web의 경우 리소스가 로드 하는데 부문별로 다를 수 있음.
- 로딩이 완료 되기 전에 해당 element를 참조 ElementNotVisibleException, NoSuchElementException 에러 발생.
- Explicit Waits : 특정 상태가 될때 까지 기다리고, 상태가 되면 바로 실행
- Implicit Waits : 주어진 시간 까지 대기
- ajax를 사용하지 않는 웹 사이트에서 단순하게 DOM구조만 변경되는 상황이면 Implicit wait를 사용해도 무방함.(DOM API 처리 속도는 굉장히 빠름.)
- 최신 웹 사이트들은 대부분 ajax요청을 통해 웹 구조를 바꾸는 SPA(Single Page App)방식이 많음. 크롤링을 진행할 때 Explicitly wait을 이용하는 것이 좋음.
Selenium Method 및 API
Single Method
함수 | 설명 |
find_element_by_id(id) | id 속성으로 요소를 하나 추출 |
find_element_by_name(name) | name 속성으로 요소를 하나 추출 |
find_element_by_css_selector(query) | css 선택자로 요소를 하나 추출 |
find_element_by_xpath(query) | XPath를 지정해 요소를 하나 추출 |
find_element_by_tag_name(name) | tag 이름이 name에 해당하는 요소를 하나 추출 |
find_element_by_link_text(text) | 링크 텍스트로 요소를 하나 추출 |
find_element_by_partial_link_text(text) | 링크의 child 요소에 포함돼 있는 텍스트로 요소를 하나 추출 |
find_element_by_class_name(name) | 클래스 이름이 name에 해당하는 요소를 하나 추출 |
Multiple Method
함수 | 설명 |
find_elements_by_id(id) | id 속성으로 요소를 여러 개 추출 |
find_elements_by_name(name) | name 속성으로 요소를 여러 개 추출 |
find_elements_by_css_selector(query) | css 선택자로 요소를 여러 개 추출 |
find_elements_by_xpath(query) | XPath를 지정해 요소를 여러 개 추출 |
find_elements_by_tag_name(name) | tag 이름이 name에 해당하는 요소를 여러 개 추출 |
find_elements_by_link_text(text) | 링크 텍스트로 요소를 여러 개 추출 |
find_elements_by_partial_link_text(text) | 링크의 child 요소에 포함돼 있는 텍스트로 요소를 여러 개 추출 |
find_elements_by_class_name(name) | 클래스 이름이 name에 해당하는 요소를 여러 개 추출 |
XPath (XML Path Language)
- W3C의 표준으로 XML(Extensible Markup Language)문서의 구조를 통해 경로(Path)위에 지정한 구문을 사용하여 항목을 배치하고 처리하는 방법을 기술하는 언어.
- XML 표현보다 더 쉽고 약어로 되어 있으며, XSL변환(XSLT)과 XML지시자 언어(XPointer)에 쓰이는 언어로 XML 문서의 Node를 정의하기 위하여 경로식(Path Expression)을 사용
문법
표현 | 설명 |
nodename | 노드명이 'nodename'인 노드 선택 |
/ | 루트 노트로부터 선택 |
// | 현재 노드로부터 문서상의 모든 노드 조히 |
. | 현재 노드 선택 |
.. | 현재 노드의 부모 노드 선택 |
@ | 현재 노드의 속성 선택 |
DOM 요소에 적용할 수 있는 method
함수 | 설명 |
clea() | 글자를 입력할 수 있는 요소의 글자를 지운다 |
click() | 요소를 클릭한다 |
get_attribute(name) | 요소의 속성 중에 name에 해당되는 속성의 값을 추출한다 |
is_displayed() | 요소가 화면에 출력되는지 확인한다 |
is_enabled() | 요소가 활성화 되었는지 확인한다 |
is_selected() | 체크박스 등의 요소가 선택 상태인지 확인한다 |
screenshot(filename) | 화면을 캡쳐해서 filename으로 저장한다 |
send_keys(value) | 키를 입력한다. 일반적으로 text 데이터를 보낸다 |
submit() | 입력 양식을 전송한다 |
value_of_css_property(name) | name에 해당하는 CSS 속성 값을 추출한다 |
Selenium Sample Code
web page 조회 시 chrome browser 실행 없이 정보 가져오기
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options)
url = 'https://www.naver.com'
driver.get(url)
객체 id나 class name으로 정보 가져오기
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options)
url = 'https://www.naver.com'
driver.get(url)
input_elem = driver.find_element(By.ID, 'query')
input_elem.send_keys('서울 날씨')
driver.find_element(By.ID, 'search_btn').click()
print(driver.find_element(By.CLASS_NAME, 'temperature_text').text)
print()
print(driver.find_element(By.CLASS_NAME, 'temperature_info').text)
동적 페이지의 정보를 selenium으로 접근하고 html 데이터는 BeautifulSoup을 이용해서 추출
# 멜론 인기차트 상위 50곡 크롤링
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
# chromedriver 실행 파일이 별도로 존재하는 경우
# driver = webdriver.Chrome('c:/chromedriver.exe')
# 설치된 chromedriver를 사용하는 경우
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options)
url = 'http://www.melon.com/chart/index.htm'
driver.get(url)
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
songs = soup.select('tr')[1:51]
idx = 0
for song in songs:
idx += 1
title = song.select('div.ellipsis.rank01 > span > a')[0].text
singer = song.select ('div.ellipsis.rank02 > a')[0].text
print(idx, title, singer, sep = ' | ')
driver.quit()
NAVER 검색창에 python을 검색하고 결과 확인하기
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.keys import Keys
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options)
driver.get('https://www.naver.com')
input_element = driver.find_element(By.ID, 'query')
input_element.send_keys('python')
input_element.send_keys(Keys.RETURN)
html = driver.page_source
bsObj = BeautifulSoup(html, 'html.parser')
ul_tag = bsObj.find('ul', {'class':'lst_type'})
lis = ul_tag.findAll('li')
for li in lis:
a_tag = li.find('a')
# print(a_tag['href'])
print(a_tag.text)
Coffebean Store 정보 조회해서 CSV 파일로 저장하기
https://www.coffeebeankorea.com/store/store.asp
매장정보 팝업에서 "자세히보기" javascript를 실행해서 상세 매장 정보 조회하기
자세히보기에 마우스 오버 시 하단에 javascript 함수가 노출되어 있음
from bs4 import BeautifulSoup
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--no-sandbox')
chrome_options.add_argument('--disable-dev-shm-usage')
driver = webdriver.Chrome('chromedriver', chrome_options=chrome_options)
def cfb_store_info(result):
cb_url = 'https://www.coffeebeankorea.com/store/store.asp'
for i in range (1, 30):
driver.get(cb_url)
time.sleep(2)
try:
driver.execute_script('storePop2(%d)'% i)
time.sleep(2)
html = driver.page_source
bsObj = BeautifulSoup(html, 'html.parser')
store_name_h2 = bsObj.select('div.store_txt > h2')
store_name = store_name_h2[0].text
store_info = bsObj.select('div.store_txt > table.store_table > tbody > tr > td')
store_address = store_info[2].text
store_phone = store_info[3].text
result.append([store_name, store_address, store_phone])
except:
continue
result = []
cfb_store_info(result)
data = pd.DataFrame(result,
columns=['매장명','주소','전화번호'])
data.to_csv('cfb_data.csv', index=False)
728x90
반응형
'Python > Web Crawling' 카테고리의 다른 글
[Web Crawling] Beautiful Soup (0) | 2022.04.27 |
---|---|
[Web Crawling] Scraping & Crawling (0) | 2022.04.27 |