본문 바로가기

WEB&서버

[WEB] XPath

https://ko.wikipedia.org/wiki/XPath

설명

W3C 표준으로, XML 문서의 구조를 통해 경로 위에 위치한 구문을 사용하여 항목을 배치하고 처리하는 방법을 기술하는 언어로, XML 문서의 노드를 정의하기 위해 경로식을 사용하고, 수학 함수 및 기타 확장 가능한 표현들이 있다.

웹 DOM 상에 존재하는 엘리먼트들의 주소를 나타내는 기술.

관련 기술

  • XSLT: XML 문서를 다른 XML 문서로 변환하는 (Extensible Stylesheet Language Transformations)
  • XPointer: 웹 상에 존재하는 XML 문서의 일부분에 주소를 부여할 수 있는 방법을 제공

종류

  1. Absolute XPath: 절대 경로 형식으로 표현 ( /html/body/div ... ). 경로 상에 엘리먼트 하나만 추가되도 XPath 구문이 무효효화되서 권장하는 방식은 아니다.
  2. Relative XPath: 상대 경로 형식으로 표현  ( //div )

사용 도구

 일반적으로 웹 사이트를 디버깅할 때 Chrome Dev Tools(F12)을 많이 사용하며, 해당 도구는 XPath 기반 검색 기능도 지원한다. 그런데, web 상의 데이터를 XPath 기반으로 검색할 때  을 이용하는 경우 문제가 발생할 수도 있다.

 Chrome Dev Tools의 경우 우리가 입력한 검색어를 두 가지 방식으로 인식한다. 하나는 단순 문자열 일치, 다른 하나는 XPath 구문이다. 간단한 사이트를 하나 만들어서 이를 검증해보자.

<!DOCTYPE html>
<html>
<head>
  <meta charset='utf-8'>
  <meta http-equiv='X-UA-Compatible' content='IE=edge'>
  <title>Page Title</title>
  <meta name='viewport' content='width=device-width, initial-scale=1'>
  <link rel='stylesheet' type='text/css' media='screen' href='main.css'>
  <script src='main.js'></script>
  <link rel="https://api.w.org/" href="https://genshin.hoyoverse.com/ko/">
</head>
<body>
  <div>
    <a href="www.google.com">google</a>
    <a href="www.naver.com">naver</a>
    <a href="www.github.com">github</a>
  </div>
  <div>
    //a
  </div>
</body>
</html>

 

위 페이지의 모든 a 태그를 검색한다고 생각해보자. 가장 간단한 방법은 더블 슬래시를 이용하여 //a로 검색하는것이다. 페이지 내에 포함된 a 태그는 3개밖에 없으므로 당연히 3개만 검색된다고 생각할 것이다.  그러나, 실제로는 5개가 검색된다.

5개의 노드가 검색되는 모습

 위에서 언급했듯 Dev Tools는 XPath 이외에 문자열 검색도 함께 수행하기 때문에, 내가 //a를 XPath로 의도하여 사용했더라도 문서 내 문자열 일치 검색에 대한 결과도 포함된다. XPath 검색만이 목적이라면 다른 수단이 필요하다.

 웹 스토어 기준 XPath helper 정도로 검색하면 나오는 확장 프로그램들을 이용할 수 있으며, 내가 본 강의는 SelectorHub를 사용했다. 단순히 XPath 검색 기능만 제공하는 것이 아니라 다른 환경(jquery, js Path 등)에서 동일한 노드를 검색하기 위한 명령어를 제시하거나, 잘못된 XPath를 수정할 수 있도록 오류 메시지를 출력하는 등 디버깅 측면에서 편리하다.

SelectorHub의 주소는 다음과 같다.

작성법

슬래시

  • single forward slash( / ): DOM 내에서 한 칸씩 이동 
    • /html/body/div[@id = 'pasword']
  • double forward slash( // ): 특정 요소로 바로 이동
    • //div[@id = 'pasword']

두가지 방식은 경로 내에서 함께 사용해도 상관 없다. ex) 

네이버 - 언론사편집에서 /html//div[@id='newsstand'] 경로로 검색한 노드

속성

@속성_이름 형태로 나타낸다. 속성 관련 정보는 대괄호 ( [ ] ) 안에 표현되어야 한다.

속성 값 비교는 [@props = 값] 형식으로 나타낸다.

순서(인덱스)

____[index] 형식으로 나타난다. XPath의 경우 매칭되는 노드를 전부 가리킨다. 해당 노드 중 특정 순서의 노드를 선택하고 싶은 경우 인덱스를 표기할 수 있다.

ex) //div[3] : 모든 div 엘리먼트 중 3번째 엘리먼트

함수

MDN 레퍼런스: https://developer.mozilla.org/en-US/docs/Web/XPath/Functions

@class, @id 등 속성(attribute)을 통해 대응되는 값을 가져올 수 있다는 점을 잘 생각하자.

  • contains(string, string): 특정 문자열이 문자열을 포함하는지 확인한다. 
    • //li[contains(@class,'MediaContentsView-module__media_item')]

contains을 이용하여 검색한 모습

  • text(): 해당 엘리먼트가 포함한 텍스트 값을 가져온다.
  • normalize-space(string): 문자열 앞 / 뒤에 대한 white-space strip을 수행한다.

이외에도 여러 함수가 있으므로, 필요할 때 살펴보자.


udemy에 무료 튜토리얼이 존재한다.

https://www.udemy.com/course/xpath-tutorial-from-basic-to-advance-level

'WEB&서버' 카테고리의 다른 글

[WEB] XPath로 SVG 요소 식별하기  (0) 2023.07.30
[WEB] XPath axes  (0) 2023.07.30
[부가정보] https 로컬에서 사용하기  (0) 2023.07.28
[WEB] MutationObserver API  (0) 2023.03.08
[WEB] console.log로 객체를 출력하지 말자  (0) 2023.02.07