TIL #23 : [HTML] XPATH 문법과 selenium에 XPATH 이용하기

셀레스틴 허·2020년 12월 28일
2
post-thumbnail

selenium 크롤링 강의 보던 중 생소한 용어를 접했다.

url = driver.find_element_by_xpath("").get_attribute("src")

그래서 이번 TIL은 XPATH이 무엇인지, 그리고 selenium과 함께 어떻게 사용되는지 정리해보기로 했다.

XPATH: Extensible Markup Language

컴퓨터에서 디렉토리에 접근하는 방식과 마찬가지로 xml도 원하는 태그나 속성을 쉽게 찾기 위해 path 문법이 나왔다. XPATH는 웹이 기록된 정보들에 접근하는 방식을 다룬 문법이며 XPATH는 다루고 싶은 모든 element들을 node단위로 처리한다.

노드 종류

node특성
element node태그
attribute node속성
text node태그의 내용
namespace node각 tag의 identity를 위해 붙이는 xmlns:prefix="URI" 형식의 attribute
processing-instruction node어떤 instruction을 수행함 (<? 태그로 시작)
comment node주석문
root nodexml 자체를 표현하는 가상 노드

[테이블 출처: https://man-about-town.tistory.com/28]

이 중 가장 많이 사용되는 node는 element, attribute, 그리고 text이다.

💡 element node

<body>
	<ul>
		<li>
   			<span>넘버원</span>
		</li>
		<li>
   			<span>넘버투</span>
		</li>
	</ul>
	<ul> 
		항목 아직 없음
	</ul>
</body>

컴퓨터 디렉토리는 중복을 허용하지 않지만 웹 특성상 중복 태그가 흔하며, XPATH는 중복태그 및 특정 노드에 대한 접근이 가능하다.

만약 li태그로 가고싶다고 가정하자. 컴퓨터 디렉토리라면 'body/ul/li'라고 적을 것이다. 그러나 XPATH에는 중복태그가 허용되며 이 코드에는 지금 li태그가 두개다. 여기서 특정 노드를 지정하고 싶다면 배열을 사용한다.

배열 사용

중복되는 태그는 배열 개념을 이용해 [1], [2] 식으로 특정 노드를 고른다. 물론 수식을 사용할 수 있으며 예를 들어 num처럼 num의 값 이하, 또는 이상인 모든 항목도 반환할 수 있다.
ex) '/body/ul//li[num>2]'를 사용하면 num의 값이 2보다 큰 모든 li를 반환한다

여기서 만약 nodename만 사용하면 nodename에 해당되는 모든 태그를 불러올 수 있다.
ex) '/body/ul//li'로 '넘버원', '넘버투'가 들어있는 태그 둘 다 가져올 수 있다

모든 태그

'//'을 사용해 하위 태그를 모두 찾을 수 있다. '//ul'이라고 쓸 경우 모든 ul을 찾아주며, 'ul//li'라고 적을 경우 ul 안에 있는 모든 li를 찾아준다.

  • 여기서 주의해야할 점은 liul 태그 안에 있기 때문에 그냥 li라고 쓰면 아무것도 못 찾는다.

  • element node는 가장 많이 쓰이는 node이기 때문에 별도의 표기 없이 사용 가능하다.

💡 attribute node

attribute node는 앞에 '@'을 붙인다. 속성을 가진 element를 찾고 싶다면 element_node[@attribute_node]을 사용하면 된다.
ex) //span[@style]: style attribute을 가지고 있는 span 태그의 element node를 모두 가져온다.

💡 text node

'text()'를 사용한다. element node안에 존재하기 때문에 element node를 먼저 써야한다.
ex) //span/text() : 모든 span태그 안에 있는 text node 추출
ex) //text(): 모든 태그 안의 text 추출

노드 선택

node특성
nodename노드명이 'nodename'인 노드 선택
/루트 노드로 부터 선택
//현재 노드로부터 문서상의 모든 노드 조회
.현재 노드 선택
..현재 노드의 부모 노드 선택
@현재 노드의 속성 선택

[테이블 출처: https://wkdtjsgur100.github.io/selenium-xpath/]

불특정 노드 선택

표현설명
nodename노드명이 'nodename'인 노드 선택
*매칭되는 모든 element 노드
*@매칭되는 모든 attribute 노드
node()현재 노드로부터 문서상의 모든 node 조회

[테이블 출처: https://wkdtjsgur100.github.io/selenium-xpath/]


selenium에 XPATH 이용하기

selenium에서는 XPATH와 같은 path language를 통해 명시적으로 element를 가져올 수 있다.
find_element_by_xpath(), find_elements_by_xpath() 메서드로 검색 가능하며, chrome 검색창을 통해 'copy xpath'로 쉽게 가져올 수 있다.

XPATH 예제

  1. //@href: href 속성이 있는 모든 태그 선택
  2. //a[@href="http://google.com"] : a태그 href 속성 중 http://google.com 값을 가진 모든 태그 선택
  3. (//a)[3] : 문서의 세번째 링크 선택
  4. (//table)[last()] : 문서의 마지막 테이블 선택
  5. (//a)[position() < 3] : 문서의 처음 두 링트 선택
  6. //table/tr/* : 모든 테이블에서 모든 자식 tr 태그 선택
  7. //div[@*] : 속성이 있는 div태그 선택

[출처: https://wkdtjsgur100.github.io/selenium-xpath/]

Reference
https://man-about-town.tistory.com/28
http://twinbraid.blogspot.com/2015/02/xpath.html
https://wkdtjsgur100.github.io/selenium-xpath/
https://www.fun-coding.org/crawl_advance5.html

profile
Software Developer / 고통은 필연, 괴로움은 선택

0개의 댓글