[一日30分 인생승리의 학습법] XPATH 사용법·작성법

 

 일본의 블로그 글을 번역한 포스팅입니다. 오역 및 직역이 있을 수 있으므로 내용 지적 언제나 환영합니다.

 

초급편


XPath란?

 XPath는 XML문장 속의 요소, 속성 등을 지정하기 위한 언어이다. XPath에는 XML문장을 트리로서 다루기 때문에, 요소나 속성의 위치를 지정하는 것이 가능하다. HTML도 XML의 일종으로 간주 될 수 있으므로, XPath를 사용하여 HTML문장의 요소를 지정하는 것도 가능하다.

 예를 들어

<html>
...
  <body>
    <h1>원피스</h1>
    <div class="item">
      <span class="brand">iQON</span>
      <span class="regular_price">12,000원</span>
      <span class="sale_price">10,000원</span>
    </div>
  </body>
</html>

 위와 같은 HTML의 경우라면, 아래와 같이 트리 구조로 나타낼 수 있다.

 

 

 XPath는 이러한 트리 구성으로 부터 요소를 얻어낸다.

 

XPath의 기초

 XPath는 로케이션 패스에의해 표현된다. 로케이션 패스란 트리구조로부터 특정 요소를 지정하기 위한 식과 같은 것이다. 로케이션 패스는 URL과 같이 "/"를 이용해 요소를 연결하여 작성한다.

 아까봤던 코드를 다시 한 번 살펴보자. 이 HTML 코드에서 "h1요소"를 얻어내는 XPath는 트리 구조상의 순서로 보자면 "html 요소 → body요소 → h1요소"로 지정하는 것이다. 

<html>
...
  <body>
    <h1>원피스</h1>
    <div class="item">
      <span class="brand">iQON</span>
      <span class="regular_price">12,000원</span>
      <span class="sale_price">10,000원</span>
    </div>
  </body>
</html>

 로케이션 패스로 표현하자면, 다음과 같다.

/html/body/h1

 즉, 아까의 그림을 다시 살펴보자면 다음과 같이 된다.

 

 

 

중급편


속성에 대해서

 class와 같이 요소를 결부하는 속성을 XPath에서는 "@"로 표현한다. "12,000원"이라는 요소를 취득하고 싶은 경우에는 XPath에는 아래와 같이 쓸 수 있다.

/html/body/div/span[@class='regular_price']

 

//를 사용하여 중간의 패스를 생략

/html/body/div/span[@class='regular_price']

 XPath는 "//"를 이용하여 노드 패스를 생략할 수 있다. "//"는 descendant-or-self의 생략형이다. 즉 기점이 되는 노드의 모든 자식들의 집합을 일컫는다. 

 예를 들어,

/html/body/div/span[@class='regular_price']

 위의 XPath를 "//"를 이용하여 생략하면 아래와 같이 쓸 수 있다.

//span[@class='regular_price']

 

지정하는 문자열이 포함되어 있는 요소를 취득하는 contains

 contains는 지정하는 문자열이 포함되어 있는 요소를 얻을 수 있다.

<img class="large_image">
<img class="small_image">
<img class="thumbnail">

 위의 HTML로부터 class에 image가 붙어 있는 것을 모두 얻고 싶은 경우, "contains"를 사용하면 된다. contains함수는 제1요소 문자열 내에, 제2인수 문자열이 포함되어 있는가를 조사하는 함수이다.  class에 image가 붙은 요소를 모두 취득하는 조건을 contains를 이용해 표현하자면 다음과 같이 쓸 수 있다.

//img[contains(@class, 'image')]

 이 XPath는 class에 image가 포함된 img요소를 취득한다는 의미가 된다.

 

 

 또한 텍스트 중에 포함되어 있는 문자를 지정하고 싶은 경우에는 text()와 contains를 합쳐서 사용한다.

<div class="item">
  <h1>원피스</h1>
  <div class="price">12,000원</div>
    <div class="description">
       겨울에 이쁘게 입을 수 있는 니트 원피스입니다.
       상품번호:100000000
    </div>
  </div>
</div>

 위의 HTML부터 "상품번호"라는 문자가 포함되어 있는 요소를 지정하고 싶은 경우에는, 아래와 같이 쓸 수 있다.

//div[contains(text(), '상품번호')]

 더욱이 "지정하는 문자가 포함된 JavaScript'를 얻고 싶은 경우에는 아래와 같이 쓸 수 있다.

//script[contains(text(), 'stock')]

 

요소의 위치 지정:position

 요소의 위치를 지정하고 싶은 경우에는 position을 사용한다. position은 지정한 노드로부터 몇 번째의 노드를 취득할 것인지 지정할 수 있다.

<ul>
  <li>색상 선택</li>
  <li>화이트</li>
  <li>레드</li>
  <li>블루</li>
</ul>

 위의 HTML에서 position()을 사용해보자. 

position()= 

 위의 HTML에서 "레드"는 li요소 중 세 번째이므로 position을 이용하면 아래와 같이 표현할 수 있다.

//li[position()=3]

또한 position()=3을 생략하여 아래와 같이 쓸 수 있다.

//li[3]

position()>

 "색상 선택"이외의 li요소를 얻고 싶은 경우에는 position을 이용하자면 아래와 같이 쓴다.

//li[position()>1]

 "색상 선택"은 li요소의 첫 번째이므로, position()>1은 "색상 선택" 외의 li요소를 의미한다.

 

 

 

텍스트 노드의 취득

 요소 내의 텍스트를 취득하고 싶은 경우에는 "text()"라는 텍스트 노드를 이용한다.

<p>S사이즈<span>레드</span></p>

 이 HTML로 부터 "S사이즈"라는 문자열만을 얻고 싶은 경우, text()를 사용하면 아래와 같이 쓸 수 있다.

//p/text()

 

not

not은 술어에서 부정을 표현한다.

<img src="http://sample.ne.jp/sample_main_image.jpg">
<img src="http://sample.ne.jp/sample_sub_image.jpg">
<img src="http://sample.ne.jp/sample_thumbnail.jpg">

 위 HTML에서 http://sample.ne.jp/sample_main_image.jpg 이외의 @src를 취득하고 싶은 경우 not을 사용하자면 다음과 같이 쓸 수 있다.

//img[not(contains(@src, 'main'))]/@src

 

or

or조건문을 XPath에서도 사용할 수 있다.

<img src="http://sample.ne.jp/sample_100.jpg">
<img src="http://sample.ne.jp/sample_200.jpg">
<img src="http://sample.ne.jp/sample_300.jpg">
<img src="http://sample.ne.jp/sample_400.jpg">
<img src="http://sample.ne.jp/sample_500.jpg">
<img src="http://sample.ne.jp/sample_600.jpg">

 위의 HTML에서 100 또는 300을 포함하는 src를 취득하고 싶은 경우 or를 사용하자면 아래와 같이 쓸 수 있다.

//td[contains(@src,'100') or contains(@src, '300')]

 또한, 100 혹은 300이외의 src를 얻고 싶은 경우에는 not과 or를 합쳐 다음과 쓸 수도 있다.

//td[not(contains(@src,'100') or contains(@src, '300'))]

 

and

 and 조건도 마찬가지로 XPath에서 사용할 수 있다.

<img src="http://sample.ne.jp/main_100.jpg">
<img src="http://sample.ne.jp/main_300.jpg">
<img src="http://sample.ne.jp/sub_100.jpg">
<img src="http://sample.ne.jp/sub_300.jpg">
<img src="http://sample.ne.jp/thumbnail_100.jpg">
<img src="http://sample.ne.jp/thumbnail_300.jpg">

 이 HTML에서 "main"과 "300"을 포함하는 src를 취득하고 싶은 경우에, and를 사용하여 어래와 같이 작성할 수 있다.

//img[contains(@src, 'main') and contains(@src, '300')]

 

 

고급편


축·노드 테스트·술어 부분

로케이션 패스에서 요소를 표현할 때, "축·노드 테스트·술어 부분"이라고 불리는 것을 사용하여 표현한다.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

이름 설명
트리 상의 위치관계를 지정한다.
노드 테스트 선택하는 노드의 형과 이름을 지정한다.
술어 부분 선택하는 노드의 집합을 임의의 식을 사용해 더욱 자세히 지정한다.
/html/body/h1

 이라는 XPath는 노드 테스트만으로 요소를 표현했다. 노드 테스트만으로는 원하는 요소를 취득할 수 없는 경우는 축이나 술어 부분을 사용하여 좀 더 상세히 요소를 지정할 수 있다.

 

술어 부분에 대해서

트리 구조도에 class 등의 속성 정보를 추가하자면 다음과 같이 된다.

 

 

 

축은 트리상의 위치관계를 일컫는 것이다. 축의 대표적인 종류로는 다음과 같은 것들이 있다.

이름 설명
self 노드 자신을 의미
child 노드의 자식 노드의 집합
parent 노드의 부모 노드의 집합
ancestor 노드로부터의 조상 노드의 집합(부모를 포함한)
descendant 노드로부터의  자손 노드의 집합
following 노드의 뒤에 따라오는 노드의 집합
preceding 노드의 앞에 나오는 노드의 집합
following-sibling 노드와 같은 계층며, 그 뒤에 따라오는 형제 노드의 집합
preceding-sibling 노와 같은 계층이며, 그 앞에 나오는 형제 노드의 집합

 축을 앞에서 본 그림에 추가하자면 다음같다. 어디를 기점으로 생각하느냐에 따라 위치 관계가 달라지지만, 이번에는 "div"를 중심으로 축을 생각해보자.

 

 

 앞서 말했듯 이번에는 div를 중심으로 생각하기로 했으므로, div자체는 기점이 되는 노드 즉 "self"가 된다. body는 dib로부터 봤을 때 한 단계 위의 계층, 즉 부모가 되므로 "parent", 3개의 span은 한 계층 아래에 위치하므로 자식인 "child"가 된다. 또한 h1요소는 div와 같은 계층이지만 div보다 앞에 위치하므로 축 중 "preceding-sibling"이 된다. 

 

child의 생략에 대해

 명시적으로 축을 지정하지 않는 경우에는 축을 child로 본다. 그러므로 기본적으로 child는 생략할 수 있다.

 

//를 이용해서 중간의 패스를 생략

 앞서 보았듯, "//"는 descendant-or-self의 생략형이다. 즉 기점이 되는 노드의 자손 집합을 의미한다. 이 "//"를 이용해 패스를 생략할 수 있다. 예를 들어,

/html/body/div/span[@class='regular_price']

 XPath를 "//"를 이용해 생략하면, 아래와 같이 쓸 수 있다.

//span[@class='regular_price']

 

축::노드 테스트[술어]

축·노드 테스트·술어부분을 사용하여 XPath를 작성하는 경우, "축::노드테스트[술어]"와 같이 작성하여 요소를 지정한다.

<html>
...
  <body>
    <h1>원피스</h1>
    <div class="item">
      <span class="brand">iQON</span>
      <span class="regular_price">12,000원</span>
      <span class="sale_price">10,000원</span>
    </div>
  </body>
</html>

 이 HTML로부터 "12,000원"의 요소를 얻는 XPath는 아래와 같이 쓸 수 있다.

/html/body/div/span[@class='regular_price']/self::text()

 

 

 또한, 생략형을 쓰자면, 다음과 같다.

//span[@class='regular_price']

 여기까지 축·노드 테스트·술어 부분에 대해 설명했다. 축·노드 테스트·술어 부분에대해 더욱 자세히 알고 싶은 경우 링크(일본어 자료)를 참고해보길 바란다.

 

지정한 요소보다 뒤에 있는 형제 요소를 갖고 오는: following-sibling::

 축에 관련된 부분에서 설명했지만, "following-sibling::"은 기점이 되는 노드와 같은 꼐층에 있으며, 그 기점이 되는 노드보다 "뒤'에 따라오는 형제 노드의 집합을 표현하는 축이다. 이 "following-sibling::"은 테이블 요소를 지정할 때 활약한다.

<table>
  <tr>
    <td>생산 국가</td>
    <td>한국</td>
  </tr>
  <tr>
    <td>소재</td>
    <td></td>
  </tr>
</table> 

 위와 같은 테이블이 준비되어 있는 경우, "면"을 어떻게 취득할까?

//td[4]

 이와 같이 쓸 수 있지만, td요소가 늘거나 줄어드는 변화가 있는 경우, //td[4]의 내용도 그에 따라 변하므로 변화에 대응할 수 있다. 그러므로 이러한 때에 "following-sibling::"을 사용한다. "면"을 얻고 싶은 경우에는 아래와 같이 쓸 수 있다.

//td[contains(*, '소재')]/following-sibling::td[1]

 

 

 

지정된 요소보다 앞의 형제 요소를 갖고 오는: precedng-sibling::

"precedng-sibling::"은 following-sibling::에 대응하는 축으로 기점이 되는 노드와 같은 계층이며, 기점이 되는 노드보다 앞에 나오는 형제 노드의 집합을 일컫는 축이다. 이것도 테이블 요소를 지정할 때에 유용하다.

<table>
  <tr>
    <td class="title">22cm</td>
    <td class="title">23cm</td>
    <td class="title">24cm</td>
  </tr>
  <tr>
    <td class="title">레드</td>
    <td class="inventory">재고 있음</td>
    <td class="inventory">재고 있음</td>
  </tr>
  <tr>
    <td class="title">블루</td>
    <td class="inventory">재고 있음</td>
    <td class="inventory">재고 없음</td>
  </tr>
  <tr>
    <td class='title'>그린</td>
    <td class='inventory'>재고 있음</td>
    <td class='inventory'>재고 있음</td>
  </tr>
</table>

 위의 HTML에서 색(레드, 블루, 그린)을 모두 취득하고 싶은 경우, 어떻게 XPath를 작성할까. 단순히 아래와 같이 작성하면 색 뿐만 아니라 사이즈까지 얻어진다. 

//td[@class='title']

 따라서 색 요소만을 얻고 싶은 경우, 아래와 같이 작성한다.

//td[@class="inventory"][1]/preceding-sibling::td

 이와 같이 작성하여 class 속성이 inventory의 td요소의 첫 번째 (td[@class='inventory'][1])의 1개 앞의 요소 (preceding-sibling::td) 즉 색을 얻을 수 있다.

 

 

 

중복되는 내용 없이 추출

<table>
  <tr>
    <td>레드</td>
    <td>레드</td>
    <td>레드</td>
  </tr>
  <tr>
    <td>블루</td>
  </tr>
  <tr>
    <td>그린</td>
  </tr>
</table>

 위와 같이 테이블이 구성되어 있을 때, 색에 대한 정보가 중복되지 않도록 추출하고 싶은 경우 아래와 같이 쓸 수 있다.

//td[not(.=preceding::td)]

 이 XPath는 td요소 중에 preceding, 즉 앞에 나오는 요소와 일치하지 않는 것들을 얻어 준다.

 

 

XPath관련 편리한 서비스


 마지막으로 XPath를 취득할 때에 추천하고 싶은 확장 기능을 소개한다. 그것은 "XPath Helper'이다. XPath Helper은 브라우저의 요소에 커서를 올리는 것만으로 XPath를 알려 주는 우수한 chrome 확장 기능이다.

 

사용예

 

 링크에서 다운로드 할 수 있다. 이 확장 기능을 사용하는 방법은 chrome 북마크바의 x라고 적힌 아이콘을 클릭, 혹은 쇼트커트로는 [Ctrl+Shift+X]로 기동할 수 있다. 그리고 취득하고 싶은 요소를 Shift를 누르고 선택하면 요소의 XPath를 간단히 취득할 수 있다.

 


참고자료

qiita.com/rllllho/items/cb1187cec0fb17fc650a



출처: https://engineer-mole.tistory.com/162 [매일 꾸준히, 더 깊이]

 

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
1035 [一日30分 인생승리의 학습법] [Tensorflow] Serving이용하여 REST API 만들기 file 졸리운_곰 2021.08.07 13
1034 [一日30分 인생승리의 학습법] Amazon SageMaker는 처음이지? 누워서 머신러닝 학습부터 배포까지 file 졸리운_곰 2021.08.05 31
1033 [一日30分 인생승리의 학습법] Apache Beam (Dataflow)를 이용하여, 이미지 파일을 tfrecord로 컨버팅 하기 file 졸리운_곰 2021.08.04 4
1032 [一日30分 인생승리의 학습법] [GCP] Apache Beam 사용하기 file 졸리운_곰 2021.08.04 5
1031 [一日30分 인생승리의 학습법] Apache Beam, Apache Airflow, Apache Atlas 설명 졸리운_곰 2021.08.04 8
1030 [一日30分 인생승리의 학습법] 블레이저 웹어셈블리 (web assembly, WASM_ Awesome Blazor ) 놀라운 오픈소스 리스트 (open source) file 졸리운_곰 2021.08.04 4935
1029 MarkDown 사용법 총정리 file 졸리운_곰 2021.07.29 23
1028 [一日30分 인생승리의 학습법] [JWT/JSON Web Token] 로그인 / 인증에서 Token 사용하기 file 졸리운_곰 2021.07.24 8
1027 [一日30分 인생승리의 학습법] JWT(JSON Web Token)을 이용한 API 인증 - #1 개념 소개 file 졸리운_곰 2021.07.24 10
1026 [一日30分 인생승리의 학습법] XPath 란 무엇입니까? file 졸리운_곰 2021.07.24 5
» [一日30分 인생승리의 학습법] XPATH 사용법·작성법 file 졸리운_곰 2021.07.24 8
1024 [Git] Github에 잘못 올라간 파일 삭제하기 졸리운_곰 2021.07.13 16
1023 [一日30分 인생승리의 학습법]AI 한국어 자연어 처리 데이터셋 목록 file 졸리운_곰 2021.07.10 23
1022 [一日30分 인생승리의 학습법] 기계독해, MRC란 무엇일까 file 졸리운_곰 2021.07.10 37
1021 [一日30分 인생승리의 학습법] 웹어셈블리를 활용한 유망한 프로그래밍 언어 프로젝트 10가지 졸리운_곰 2021.07.02 13
1020 [一日30分 인생승리의 학습법] Windows 10에 Minikube 설치하기 file 졸리운_곰 2021.06.27 26
1019 [一日30分 인생승리의 학습법] 윈도우2016 서버에 Docker 설치하며 겪은 시행착오 기록 file 졸리운_곰 2021.06.26 11
1018 [초보용] Git 되돌리기( Reset, Revert ) file 졸리운_곰 2021.06.22 15
1017 [DOCKER] Windows Server 2016에서 도커 설치하기 졸리운_곰 2021.06.13 39
1016 [docker, windows server 2016] Installing Docker onto Windows Server 2016 file 졸리운_곰 2021.06.13 6
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED