본문 바로가기

개인프로젝트

[Python]멜론 노래 가사 추출하기(2)_셀레니움은 어떻게 요소들을 찾는가? with 캐글

저번 시간에는 크롤링에 관련된 용어 정리와 개발환경 세팅을 하였다.

이번 시간에는 저번 시간에 만든 크롤러가 어떻게 작업을 수행하는지 과정을 살펴볼 예정이다.

 

먼저 기본적으로 셀레니움은 사람이 웹페이지를 들어가 상호작용하는 것처럼 동작된다. 

사람은 웹페이지 상에 구현된 버튼을 보고 클릭을 하지만 셀레니움은 어떻게 버튼을 찾고 구분을 할까?

 

셀레니움은 다음과 같은 Locater들을 사용해서 요소를 찾는다.

로케이터 설명
class name Class name이 같은 요소를 찾는다(복합 클래스 이름은 허용되지 않는다)
css selector CSS selector이 일치하는 요소를 찾는다.
id ID 속성이 일치하는 요소를 찾는다.
name Name 속성이 일치하는 요소를 찾는다.
link text 보이는 텍스트가 검색 값과 일치하는 anchor 요소(a 태그)를 찾는다.
partial link text 보이는 텍스트가 검색 값을 포함하는 anchor 요소(a 태그)를 찾는다.(여러 요소라면 첫번째 요소만 검색된다.)
tag name 검색값과 일치하는 태그이름을 가진 요소를 찾는다.
xpath Xpath 표현이 일치하는 요소를 찾는다.

 

find_element 와 위의 Locater 들을 통해 웹페이지의 요소를 찾을 수 있다.

find_element는 다음과 같이 사용이 가능하다.

 

드라이버이름.find_element(로케이터,"검색할 값")

ex) driver.find_element(By.CSS_SELECTOR,".btn.button_icons.type03.song_info")

 

(* find_element_by_css_element나 find_element_by_ .. 같은 것들은 기존의 구버전에서 사용하던 것으로

deprecated된 것으로 최신 버전의 셀레니움에선 사용이 되지 않음에 주의)

By.CLASS_NAME

class 이름이 일치하는 요소를 찾을 때 사용한다.

 

네이버의 메일 부분을 예시로 들어보자. 아래의 코드로 구현된 메일 부분이다.

 

<a href="https://mail.naver.com/" class="nav" data-clk="svc.mail"><i class="ico_mail"></i>메일</a>

 

driver.get("https://naver.com")
driver.find_element(By.CLASS_NAME,"nav").text

 

CLASS 이름으로 nav를 사용하였으므로 다음과 같이 해당 요소를 찾을 수 있다.

 

 

By.CSS_SELECTOR

CSS 선택자로 찾을 때 사용한다. 아까와 같은 메일 부분의 이미지와 HTML코드이다.

 

<a href="https://mail.naver.com/" class="nav" data-clk="svc.mail"><i class="ico_mail"></i>메일</a>

 

 

여기서는 css 선택자로 class를 사용하였고

해당 선택자는 CSS 스타일에서. nav이므로 다음과 같이 해당 요소를 찾을 수 있다.

 

driver.get("https://naver.com")
driver.find_element(By.CSS_SELECTOR,".nav").text

 

 

*CLASS 선택자가 아니라 ID선택자여도 CSS 스타일 부분에 정의된 이름을 써주면 된다.

 

 

By.ID

요소의 ID를 통해서 해당하는 요소를 찾는다.

 

이번에는 네이버의 다크모드로 보기/라이트모드로 보기 부분을 예시로 들어보겠다.

 

<button id="NM_darkmode_btn" type="button" role="button" class="btn_theme" aria-pressed="false"> <span class="blind">라이트 모드로 보기</span> </button>

 

해당 경우는 다음과 같이 해당 요소를 찾을 수 있다.

 

driver.get("https://naver.com")
driver.find_element(By.ID,"NM_darkmode_btn").text

 

 

 

By.NAME

검색값과 Name 속성이 일치하는 요소를 찾을 때 사용한다.

 

네이버를 한번 예시로 들어보자.

 

 

네이버에서 더 보기 창을 누르면 뜨는 메뉴이다.

이 세부 메뉴들은 각각의 name성분을 가지고 있어서 By.NAME으로 요소들을 찾을 수 있다.

구독 부분을 찾아보도록 하자.

 

 

<a href="https://me.naver.com/tab/news.nhn" name="myfeed" data-clk="map.mysub">구독</a>

 

구독 부분에 해당하는 HTML 코드이다.

 

<a href="#" role="button" class="btn_more" data-clk="svc.more" data-edit="N">더보기</a>

 

더 보기 부분의 HTML코드이다.

 

 

구독 메뉴 부분은 더 보기를 눌러야 뜨는 세부메뉴 중 하나이므로

구독 메뉴를 찾기 위해서는 더보기 메뉴를 먼저 클릭한 것과 같은 작업을 해주어야 한다.

더 보기 메뉴를 클릭하기 위해 아까 사용했던 By.CLASS_NAME을 통해 찾고. click()으로 클릭을 수행해 준다.

그리곤 By.NAME으로 "myfeed"를 검색값으로 요소를 찾아주면 된다.

 

driver.get("https://naver.com")
time.sleep(1)
driver.find_element(By.CLASS_NAME,"btn_more").click()
time.sleep(1)
driver.find_element(By.NAME,"myfeed").text

 

다음과 같이 잘 작동하는 것을 확인할 수 있다.

 

 

By.LINK_TEXT

보이는 텍스트가 검색 값과 일치하는 anchor 요소(a 태그)를 찾을 때 사용한다.

여기서 보이는 텍스트란 <a> 태그로 둘러싸진 부분 내부의 텍스트 부분을 의미한다.

아래의 경우는 메일이 이에 해당한다고 볼 수 있다.

 

<a href="https://mail.naver.com/" class="nav" data-clk="svc.mail"><i class="ico_mail"></i>메일</a>

 

이 경우는 아까 위에서 살펴보았던 메일 부분을 이런 식으로 By.LINK_TEXT를 통해서도 찾을 수가 있다.

 

driver.get("https://naver.com")
driver.find_element(By.LINK_TEXT,"메일").text

 

By.PARTIAL_LINK_TEXT

보이는 텍스트가 검색 값을 포함하는 anchor 요소(a 태그)를 찾을 때 사용한다.

아까 살펴보았단 By.LINK_TEXT랑 비슷하지만 일치하지 않고 검색 값이 일부만 포함되어도 된다는 차이가 있다.

 

driver.get("https://naver.com")
driver.find_element(By.PARTIAL_LINK_TEXT,"메").text

 

By.TAG_NAME

요소의 태그이름(h1, div, 등등..)으로 찾을 때 사용한다.

 

네이버의 h1태그를 예시로 들어보자면 다음과 같다.

 

 

<h1 class="logo_default">
<a href="/" class="logo_naver" data-clk="top.logo"><span class="blind">네이버</span></a>
</h1>

 

driver.get("https://naver.com")
driver.find_element(By.TAG_NAME,"h1").text

 

 

By.XPATH

요소의 Xpath를 통해 요소를 찾을 때 사용한다.

 

Xpath는 크롬의 경우 F12를 누른 뒤 해당태그 부분을 우클릭해서 아래의 작업으로 얻을 수 있다.

driver.get("https://naver.com")
driver.find_element(By.XPATH,"//*[@id=\"header\"]/div[1]/div/div[1]/h1").text

 

 

 

이번시간에는 셀레니움은 어떻게 요소를 찾는지에 관해 알아보았다.

다음시간엔 위 작업들을 토대로 멜론에서 가사추출을 해보도록 하겠다.

 

잘못된 부분이 있다거나 이해하기 어려운 부분, 혹은 질문이 있다면 언제든지 댓글로 달아주시면 최대한 빨리 답변 및 수정해드리도록 하겠습니다!

 

참조

 

https://www.selenium.dev/documentation/webdriver/getting_started/first_script/

 

Write your first Selenium script

Step-by-step instructions for constructing a Selenium script

www.selenium.dev

https://www.selenium.dev/documentation/webdriver/elements/locators/

 

Locator strategies

Ways to identify one or more specific elements in the DOM.

www.selenium.dev

 

https://www.selenium.dev/documentation/webdriver/elements/finders/

 

Finding web elements

Locating the elements based on the provided locator values.

www.selenium.dev

 

https://mundrisoft.com/tech-bytes/code-to-located-element-by-name-using-selenium-webdriver/

 

Selenium WebDriver Locator by Name

Locator Type: Name Name attribute is unique throughout html document except checkbox and radio button. Name attribute is not unique if multiple radio button and checkboxes used with same name. Name attribute used with iframe which can be used to switch dri

mundrisoft.com