일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 | 31 |
- 데이터 웨어하우스
- airflow.cfg
- selenium
- yarn
- spark
- 데이터마트
- 데이터파이프라인
- truncate
- SQL
- dag 작성
- docker-compose
- 알고리즘
- dag
- airflow
- AWS
- Hive
- docker hub
- Django Rest Framework(DRF)
- Django
- ELT
- snowflake
- Serializer
- docker
- 웹 스크래핑
- redshift
- Kafka
- ETL
- 컨테이너 삭제
- 웹 크롤링
- 데이터레이크
- Today
- Total
개발 기록장
04. 파이썬으로 웹 데이터를 크롤하고 분석하기(4) 본문
학습 주제: Selenium, Wait and Call, 마우스/키보드 이벤트 처리, Jupyter Lab
Selenium
: 브라우저 자동화
- Selenium 설치
%pip install selenium
- Web Driver
- 웹 브라우저를 제어할 수 있는 자동화 프레임워크.
%pip install webdriver-manager
- Selenium 시작
# selenium으로부터 webdriver 모듈 불러오기
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
#크롬 실행 및 요청 보내기
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get('http://www.example.com')
#page_source 속성 확인
print(driver.page_source)
- with - as
- Chrome 창 계속 켜져 있는 것 방지
- 주어진 명령이 끝나면 driver 종료
- Driver에서 특정 요소 추출
- 요소 하나 찾기
- find_element(by, target)
by: 대상을 찾는 기준: ID, TAG_NAME, CLASS_NAME, ...
target: 대상의 속성
#By import
from selenium.webdriver.common.by import By
# p 태그 요소 하나 찾기
with webdriver.Chrome(service=Service(ChromeDriverManager().install())) as driver:
driver.get('http://www.example.com')
print(driver.find_element(By.TAG_NAME, "p" ).text)
- 요소 여러개 찾기
- find_elements(by, target)
by: 대상을 찾는 기준: ID, TAG_NAME, CLASS_NAME, ...
target: 대상의 속성
Wait and Call
: 동적 웹 사이트의 지연 시간 문제를 해결하면서, 스크래핑 진행
- Implicit Wait vs. Explicit Wait
- Implicit Wait(암묵적 기다림): 특정 요소에 대한 제약을 통한 기다림
ex) 5초동안 기다려 하지만, 그 전에 렌더링이 다 되면 그냥 진행해.
- Explicit Wait(명시적 기다림): 로딩이 완료될 때까지 지정한 시간 동안 기다림
ex) 로딩이 완료될 때까지, 5초동안 기다려.
- XPath
- XML, HTML 문서 등의 요소 위치를 경로로 표현하는 것.
- 스크래핑 방지를 위해 생성한 랜덤 class이름에 대응하여, 위치를 활용함.
- Chrom에서 요소 Xpath 얻는 법: ctrl -> 검사 -> 해당 요소 ctrl -> copy -> copy Xpath
- ex) //*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]
# 스크래핑에 필요한 라이브러리 불러오기
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
# 예시 사이트에 요청 진행 및 예시 사이트의 첫 번째 이벤트 제목 가져오기
driver = webdriver.Chrome(service = Service(ChromeDriverManager().install()))
driver.get('https://indistreet.com/live?sortOption=startDate%3AASC')
driver.find_element(By.XPATH,'//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]').text
- Implicit Wait
- .implicitly_wait(): 암시적 기다림 함수
- 반드시 정해진 시간을 기다리는 것 X -> 로딩 완료될 때까지의 한계 시간
# 10초동안 Implicit Wait
from selenium.webdriver.support.ui import WebDriverWait
with webdriver.Chrome(service = Service(ChromeDriverManager().install())) as driver:
driver.get('https://indistreet.com/live?sortOption=startDate%3AASC')
driver.implicitly_wait(10) #일단 10초를 기다리는데 그 전에 렌더링이 끝나면 넘어감
print(driver.find_element(By.XPATH,'//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]').text)
- Explicit Wait
- WebDriverWait():
until(): 인자의 조건이 만족될 때까지
until_not(): 인자의 조건이 만족되지 않을 때까지
# Explicit Wait
# 특정 요소가 준비되면 가져와라: 조건 명시
from selenium.webdriver.support import expected_conditions as EC
with webdriver.Chrome(service = Service(ChromeDriverManager().install())) as driver:
driver.get('https://indistreet.com/live?sortOption=startDate%3AASC')
# explicit wait로 변경
element=WebDriverWait(driver,10).until(EC.presence_of_element_located((By.XPATH,'//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]')))
print(element.text)
- 여러 공연 제목 가져오기
- 여러 공연 제목에 해당하는 XPath:
//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[1]/div/a/div[2]/p[1]
//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[2]/div/a/div[2]/p[1]
//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[3]/div/a/div[2]/p[1]
# 10개의 제목 스크래핑
with webdriver.Chrome(service = Service(ChromeDriverManager().install())) as driver:
driver.get('https://indistreet.com/live?sortOption=startDate%3AASC')
driver.implicitly_wait(10)
for i in range(1, 11): #1~10
#format 함수로 인자 변경
element = driver.find_element(By.XPATH, '//*[@id="__next"]/div/main/div[2]/div/div[4]/div[1]/div[{}]/div/a/div[2]/p[1]'.format(i))
print(element.text)
마우스 이벤트 처리하기
: 로그인 과정 자동화 - '로그인' 창 접속하기
: 로그인 버튼 누르기
- Mouse Event
- 마우스 움직이기(move)
- 마우스 누르기(press down)
- 마우스 떼기(press up) 등...
- 로그인 창 접속
1. find_element(): 입력하고자 하는 대상 찾기
2. click: 입력하고자 하는 내용 전달
3. .perform(): 동작 발생
# 스크래핑에 필요한 라이브러리 불럭오기
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
#웹 사이트 요청, 지연 시간
driver = webdriver.Chrome(service = Service(ChromeDriverManager().install()))
driver.get("https://hashcode.co.kr/")
driver.implicitly_wait(0.5)
#Xpath(위치)로 로그인 버튼 요소 찾기 및 마우스 이벤트 실행
button = driver.find_element(By.XPATH, '//*[@id="main-app-header"]/header/section/div/div/div/a[1]')
ActionChains(driver).click(button).perform()
키보드 이벤트 처리하기
: 로그인 과정 자동화 - '아이디, 비밀번호' 입력하기
: input 태그의 form에 키보드 입력
- Keyboard Event
- 키보드 누르기(press down)
- 키보드 떼기(press up) 등...
- 아이디/비밀번호 입력
1. find_element(): 입력하고자 하는 대상 찾기
2. send_keys_to_element: 입력하고자 하는 내용 입력
3. .perform(): 동작 발생
# 스크래핑에 필요한 라이브러리를 불러오기
from selenium import webdriver
from selenium.webdriver import ActionChains
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
# driver를 이용해 해당 사이트에 요청을 보내봅시다.
import time
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()))
driver.get("https://hashcode.co.kr")
time.sleep(1) #지연시간
# 내비게이션 바에서 "로그인" 버튼 누르기
button = driver.find_element(By.XPATH, '//*[@id="main-app-header"]/header/section/div/div/div/a[1]')
ActionChains(driver).click(button).perform()
time.sleep(1)
# "아이디" input 요소에 아이디 입력
id_input = driver.find_element(By.XPATH,'//*[@id="main-app-account"]/div/div[2]/div/div[2]/div[1]/div/div[2]/div[2]/input')
ActionChains(driver).send_keys_to_element(id_input,"내 아이디").perform
time.sleep(1)
# "패스워드" input 요소에 비밀번호 입력
pw_input = driver.find_element(By.XPATH,'//*[@id="main-app-account"]/div/div[2]/div/div[2]/div[1]/div/div[2]/div[4]/input')
ActionChains(driver).send_keys_to_element(pw_input,"내 비밀번호").perform
time.sleep(1)
# "로그인" 버튼을 눌러 로그인 완료
loginbutton = driver.find_element(By.XPATH,'//*[@id="main-app-account"]/div/div[2]/div/div[2]/div[1]/div/div[2]/button')
ActionChains(driver).click(loginbutton).perform()
time.sleep(1)
- implicity vs. time sleep
- implicity: 로딩 기다리다가 중간에 완료되면 넘어감(한계 시간)
- time sleep: 지정된 시간을 반드시 기다림
Jupyter Lab
: Interactive한 Python 코드 작성 및 공유를 위한 개발 도구
- Jupyter Lab 설치
pip install jupyterlab
- Jupyter Lab 조작법
- Jupyter Lab Mode
- ESC: 명령모드
- Enter: 입력모드
- 노트북 파일 2가지
- Y: Code Cell
- M: Markdown Cell
- Cell 추가
- A(bove): 현재 Cell 위에 새로운 Cell 추가
- B(elow): 현재 Cell 아래에 새로운 Cell 추가
- Cell 삭제
- dd: 현재 Cell 삭제
- Cell 실행
- ctrl/cmd + Enter: 현재 Cell 실행
- Markdown
1. Header(#, ##, ###, ...): 제목, 소제목
2. Italic(*...*, _..._ ): 기울임체
3. Bold(**...**, __...__): 볼드체
4. Strikethrough(~...~): 취소선
5. Unordered List(-..., *...): 순서 없는 리스트
6. Ordered List(1. ..., 2. ...): 순서 있는 리스트
7. Code(`...`): 코드 삽입
8. Code Block(```...```): 코드 블록 삽입
공부하며 느낀점
Selenium을 통해 로그인을 진행할 수 있다는게 놀라웠다. 이를 응용하면 더 많은 것을 할 수 있을 것 같다. 또 평소 Jupyter Lab을 마우스로만 사용해서 조금 불편했는데, 단축키를 학습하게 되어 편리하다.
'데브코스(DE) > 파이썬으로 웹 크롤링 및 분석' 카테고리의 다른 글
05. 파이썬으로 웹 데이터를 크롤하고 분석하기(5) (1) | 2024.04.05 |
---|---|
03. 파이썬으로 웹 데이터를 크롤하고 분석하기(3) (1) | 2024.04.03 |
02. 파이썬으로 웹 데이터를 크롤하고 분석하기(2) (0) | 2024.04.02 |
01. 파이썬으로 웹 데이터를 크롤하고 분석하기(1) (0) | 2024.04.01 |