BeautifulSoup = 자바스크립트를 사용하여 동적으로 생성된 정보는 가져올 수 없다.
동적 홈페이지를 활용하기 위해서 사용하는 패키지
Selenium
- URL만으로 접근할 수 없는 홈페이지에 접근
- 크롤링이 목적 아닌 만들어진 홈페이지를 테스트하고 웹 브라우저를 제어할 목적으로 사용된다
- 브라우저를 직접 제어하여 사이트의 다양한 HTML 요소에 클릭, 키보드 입력 등 이벤트 처리를 할 수 있다.
- 웹 드라이저로 브라우저를 직접 띄우고 제어하여 상대적으로 로딩이 오래 걸림
- 따라서 time 모듈의 sleep 함수와 함께 조금씩 시간차를 두고 실행하는 것이 좋다.
패키지 설치 방법
# 아나콘다 프롬프트
pip install selenium
pip install webdriver_manager
# 아나콘다 노트북
!pip install selenium
!pip install webdriver_manager
Webdriver 사용
2가지 방식이 존재한다.
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
# 1. 웹드라이버 동적 다운로드 방식
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options = webdriver.ChromeOptions())
# 2. 기 설치돤 웹 드라이버 구동 방식
s = Service(r'c:\DEV\chromedriver\chromedriver.exe') #설치된 웹 드라이버의 경로 지정
driver = webdriver.Chrome(service = s)
HTML 정보읽기
- find_elements(): find_all()과 유사하다. 해당하는 조건 모두 검색하여 리스트로 반환
- find_element(): find()와 유사하다. 해당 하는 조건중 가장 먼저 검색된 것 선택
- by 속성: 검색 기준 지정
-value 속성: 태그 이름 지정
By.ID : 태그의 id값으로 추출 | By.XPATH: 태그의 경로로 추출(select()와 유사) | By.TAG_NAME: 태그 이름으로 추출 | By.CLASS_NAME: 태그 클래스 이름으로 추출 |
By.NAME: 태그의 from name 값으로 추출 | By.LINK_TEXT: 링크 텍스트값으로 추출 | By.CSS_SLSCTOR: css 선택자로 추출 |
이벤트 제어(대표적 3개)
click(): 마우스 클릭 | send_keys(): 키보드 입력 | excute_script(): 자바스크리트 삽입 |
# find_element()함수
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
# 웹드라이버 동적 다운로드 방식
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options = webdriver.ChromeOptions())
driver.get('https://www.daum.net')
ele = driver.find_element(by=By.LINK_TEXT,value='카페')
# 다음 홈페이지에서 링크에 있는 카페라는 단어의 정보를 찾음
print(ele)
# <selenium.webdriver.remote.webelement.WebElement (session="52fd3aac76b4add2674149c409cbbbe8", element="B6968CF2274E93EA6D82D664D4228D47_element_23")>
# 따로 태그가 나오는 것은 아니다.
print(type(ele))
print(ele.text)
# Click()
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options = webdriver.ChromeOptions())
driver.get('https://www.daum.net')
ele = driver.find_element(by=By.LINK_TEXT,value='카페')
ele.click()
# send_keys()
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options = webdriver.ChromeOptions())
driver.get('https://www.daum.net')
ele = driver.find_element(By.ID,'q') # 고유한 id가 'q'
ele.send_keys('python')
ele.send_keys(Keys.ENTER) # 특수문자
BeautifulSoup 과 연결하기
bs = BeautifulSoup(driver.page_source,'lxml')
m = BeautifulSoup(res,'lxml')와 유사한 형식. (driver.page : drivermanager 를 통해 동적 페이지를 얻어온 것)
[실습] 네이버 로그인하기
필요한 패키지 호출
id = 'Myid', pw = 'Mypwd' 를 변수로 설정해 놓아 입력할 수 있는 상태로 만든다. (개인정보 보호를 위해 변경)
By.ID 활용하여 태그를 검색하였다.
<input type="text" id="id" name="id" placeholder="아이디" title="아이디" class="input_text" maxlength="41" value="">
<input type="password" id="pw" name="pw" placeholder="비밀번호" title="비밀번호" class="input_text" maxlength="16">
로그인버튼 활용하고 + 이벤트 click() 사용
<button type="submit" class="btn_login" id="log.login"><span class="btn_text">로그인</span></button>
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options = webdriver.ChromeOptions())
driver.get('https://www.naver.com')
ele = driver.find_element(By.CLASS_NAME,'MyView-module__link_login___HpHMW')
ele.click() # 간혹 클릭 이벤트가 적용되지 않는 경우에는 send_keys(Keys.ENTER) 를 이용하면 됨
id = 'Myid'
pw = 'Mypwd'
ele = driver.find_element(By.ID,'id')
ele.send_keys(id)
ele = driver.find_element(By.ID,'pw')
ele.send_keys(pw)
ele = driver.find_element(By.CLASS_NAME,'btn_login')
ele.click()
코드를 실행시키면 로봇으로 인식하게 되어 해당 로봇이 아닌지 확인하는 프로그램을 실행하게 된다.
그것을 해결하기 위해 자바스크립트로 작성.
excutr_script: 자바스크리트 삽입
driver.execute_script(f"document.getElementById('id').value = '{id}'")
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options = webdriver.ChromeOptions())
driver.get('https://www.naver.com')
ele = driver.find_element(By.CLASS_NAME,'MyView-module__link_login___HpHMW')
ele.click() # 간혹 클릭 이벤트가 적용되지 않는 경우에는 send_keys(Keys.ENTER) 를 이용하면 됨
id = 'Myid'
pw = 'Mypwd'
# 로봇에 의해 클릭되지 못 하도록 막았기 때문에 자바스크립트로 처리하여 로그인함
driver.execute_script(f"document.getElementById('id').value = '{id}'")
driver.execute_script(f"document.getElementById('pw').value = '{pw}'")
ele = driver.find_element(By.CLASS_NAME,'btn_login')
ele.click()
자바 스크립트를 활용하여 정상적으로 로그인 되었다.
'국비 교육 > 데이터' 카테고리의 다른 글
[데이터 수집] BeautifulSoup + Selenium 실습 (0) | 2023.11.02 |
---|---|
[데이터 수집] 셀레니움 - 2 (구글 이미지 실습) (0) | 2023.11.02 |
[데이터 수집] 웹 스크래핑 예제 - 네이버 뉴스 페이지 언론사 목록, 네이버 웹툰 제목 가져오기, 다음 영화 사이트에서 영화 포스터 다운로드 (0) | 2023.11.01 |
[데이터 수집] 웹 스크래핑 - 2 (0) | 2023.10.31 |