노무현 대통령 배너

Make A Wish!!

SERAPHMATe's LifeLog


IBM 문서 http://www.ibm.com/developerworks/xml/library/j-jtp03225.html의 자체번역입니다. 이상하더라도 이해하시길..=_=)


자바 이론과 실습 : XQuery를 이용한 Screen-Scraping
 - XQuery는 HTML 추출과 변환을 쉽게 할 수 있게 합니다.

XQuery 는 XML 문서들로부터 정보를 추출해내기 위한 W3C 표준으로 현재까지 14번째 초안으로 확장되었다. XQuery의 주된 관심사가 반-구조화된 문서 데이터들 기반의 쿼리에 대한 것인 반면에, XQuery는 몇몇의 실용적인 면에서 놀라울 정도로 매우 효과적일 수 있다. 이번 달의 '자바 이론과 실습'은 컬럼니스트 Brian Goetz가 어떻게 XQuery가 HTML Screen-Scraping 엔진으로써 효과적으로 사용될 수 있는지 보여줄 것이다.

지난 달, Java Technology의 전문가 Sam Pullara는 자바 사용가능한 최신형 핸드폰, Nokia 6630을 보여주었다. 그것은 모든 기술 -- Embedded JVM, GPRS, Bluetooth -- 이 담겨있었지만, 그것은 모든 스마트폰이 앓고 있는 동일한 전염병 -- 한정된 화면 크기 -- 을 앓고 있었다.  몇몇의 웹 사이트들은  CellPhone기반의 브라우저를 지원하고 있고, 내장 브라우저들도 작은 화면 내에서 페이지를 효과적으로 나타내기 위해 노력하고 있지만, 폰 화면에서 일반적인 웹 페이지를 보기 위해서는 코끼리를 당신의 자동차 뒷 좌석에 밀어넣는 것(당신과, 당신의 자동차와, 코끼리 모두에게 불만을 주는)만큼의 많은 노력이 필요하다. Sam은 그가 좋아하는 웹 사이트에서 데이터를 Screen-Scraping하고, 작은 화면을 위해 그 데이터들을 Reformatting하는 단순하고, 멋진 솔루션을 만들어 두었다.


새로운 접근

당신은 HTML문서로부터 데이터를 추출하기 위한 많은 접근 방법을 사용할 수 있다. 나는 Sam이 가져온 접근법, Screen-Scraping 툴을 이용한 것(페이지로부터 적절한 데이터를 추출)이든, Stylesheet 툴(데이터를 재포맷하여 스크롤링 없이 페이지를 잘 맞출 수 있게)을 이용한 것이든, XQuery를 이용한 접근법을 정말로 좋아한다. 적은 양의 기반조직과 몇몇의 꽤 단순한 XQuery 표현으로, 다량의 데이터 소스와 관련된 데이터 -- 교통정보, 날씨, 재정적인 시세 등 -- 를 폰에서 멋지게 보여지도록 추출할 수 있게 된다.

나는 종종 HTML 페이지를 Screen-Scraping하는 상황을 겪는데, 이 페이지들은 특정한 문제에 대하여 매우 민감한 솔루션으로 보인다.(?) 그러나 Screen-Scraping을 위한 자바기반의 툴킷은 매우 적다. 많은 HTML 파싱 툴들이 사용 가능하지만, 그것들은 보통 충분한 추상적인 성능이 부족하고, HTML을 따르며 범용으로 사용하기엔 한계가 있고, 오랜 시간동안 구조가 변화되고 동적으로 생성되는 페이지들을 다루기에는 부족하다.

저품질의 HTML과 훌륭한 XML-처리 세트간의 차이를 연결하기 위해, 당신은 머저 HTML을 XML로 컨버트 할 필요가 있다. 다수의 툴이 당신이 이러한 일을 하는 것을 도와준다. ; JTidy 툴킷은 그 일을 멋지고 쉽게 해준다. JTidy는 HTML을 일반적인 품질(다시 말하면, 나쁜)로 읽어들일 수 있도록 설계되어 있고, 명확한 어떤 것을 출력하며, 또한, XML 파서에 제공될 수 있는 HTML 문서를 탐색하기 위한 DOM 인터페이스를 제공한다. Listing 1에 있는 코드는 HTML 문서를 InputStream으로부터 읽어들이고, 문서에 대한 DOM표현을 생성할 것이다.



이 러한 간단한 변환으로, 당신은 거의 모든 웹페이지들을 XML 문서로 처리할 수 있고, 당신이 데이터를 추출하기 위하여 -- SAX, XSL, XPath -- 선호하는 XML 툴을 적용하고, 지정할 수 있다. XSL은 XML로부터 정보를 추출하고, 그것의 표현을 변환해 주기 위한 설계라는 명확한 목적이 있는 선택이 있는 반면에, 만약 이미 당신이 그것을 알지 못한다면, XSL은 명백한 배움 단계가 있다. 그리고 극도로 단순한 XSL 변환일지라도 매우 귀찮게 복잡하다. XPath는 추출이라는 부분 -- XSL과 XQuery 모두 컨텐트 선택에 사용됨 -- 에서 매우 훌륭한 후보이고, 당신이 XPath를 당신이 필요로하는 데이터를 꺼내고, 스스로 HTML 포맷팅하기 위해 쉽게 사용되지만, XQuery는 그것을 훨씬 쉽게 해결해준다.



XQuery : (터무니없이) 짧은 투어

XQuery 는 잠재적으로 매우 큰 XML 데이터셋으로부터 데이터를 추출하기 위해 설계되었다. 입력 데이터 셋은 XML 문서일 필요는 없지만 XML 문서일 수도 있다. 그러나 또한, 입력 데이터 셋은 XML 데이터베이스 내에 인덱스 되어 저장된 문서들의 집합일 수도 있고, 또는 관계형 데이터베이스 내의 테이블의 집합일 수도 있다. SQL처럼 XQuery는 추출, 종합, 모음, 여러 다수의 데이터셋으로부터 데이터를 조합하는 기능을 포함한다.

단지 JSP, ASP, Velocity등의 템플릿 언어들의 표현처럼 XQuery는 두개의 도메인 -- Presentation Domain과 Computational Domain -- 으로부터 단일한 조합 문법으로 요소들을 조합한다.그 결과는 이미 스스로를 평가하기 위해 유효한 XQuery 표현으로 된 XML 문서이다.이 문서는 또한 "for"나 "let"처럼 XML 요소들을 혼합할수 있는 언어 구문을 가지고 있다.

Listing 2는 책들의 출판 목록을 보여주는 샘플 XML 문서, bib.xml을 보여준다. 나는 당신에게 XQuery가 하는 일에 대해 맛을 보여주고, 그리고 Screen-Scraping 예제로 넘어가기 위해, 몇 줄의 간단한 XQuery 표현을 보여줄 것이다. XQuery 문법과 Use-Case를 커버하기 위해서는 수 백페이지가 소요된다. -- 좀더 자세한 참조 자료와 예제는 Resource 섹션을 참조하라.



Listing 3은 1991년 이후 Addison-Wesley에서 출간된 모든 책들을 선택하고, 그 책들의 제목을 추출하고, 제목들을 bulleted list(<ul>)로 포매팅하기 위한 XQuery를 보여준다. "Presentation mode"(<ul> 또는 <li> 등의 태그같이 출력으로 직접 통과될 데이터)에서 "Code mode"까지의 모드 전환은 중괄호로 표시된다. ; "Code mode"에서 "Presentation mode"로의 묵시적인 전환은 return 절 이후에 즉시 발생한다.



"for" 문으로 시작되고, "Flower Expression"이라고 종종 불리는 (약어 'FLWOR' - for-let-where-order-return 로부터) 쿼리 문법은 이 예제에서 bib.xml 문서 내의 <book>노드의 집합은 XPath의 표현이 사용되었고,나아가 특정한 쿼리 조건(the publisher is Addison-Wesley, and the publication year is after 1991)에 부합하는 노드들을 걸러내는 것 처럼 문서로부터 XML 노드들의 순서를 선택한다. 이 각각의 노드들을 위해 이 문법은 마크업(<li> 태그)과 code(각각의 <book>노드에서 <title> 요소의 컨텐츠를 추출)의 혼합된 표현을 처리해준다.

이 단순한 XQuery 예제는 XQuery의 여러 형태를 보여준다. -- 하나의 문서 내에서의 Presentation과 Code의 혼합, XPath의 사용, 대체의 사용($b 참조), 평범하지 않은 Query 표현, XQuery 함수(data()), 그리고 출력되는 문서의 구조는 입력되는 문서의 구조와 일치하지 않아도 된다는 사실.

Listing 4는 출판 목록내의 단일한 <count> 요소에서 각각의 출판사 수를 출력하기 위한 좀 더 간단한 XQuery 표현을 보여준다. 이전의 예제처럼 노드들의 세트를 선택하기 위해서 XPath 표현을 사용하고, 노드의 개수를 세고, 개별적인 값을 선택하기 위한 XQuery 기능을 적용했다. bib.xml 문서내의 개별적인 출판사의 수를 숫자로 평가한다.



이러한 예제들은 XQuery에 의해 수행되는 쿼리들의 형태의 표면을 겨우 가져온다. -- 그것들은 단순히 당신이 이 예제들로 할 수 있는 것들의 종류에 대해 맛보기만 줄 뿐이다. 그리고 당신이 선택한 포맷으로 XML 문서들을 변환하기 위해 XQuery를 어떻게 사용해야 하는지를 제안한다. XQuery가 가진 능력이 다량의 문서 기반의 쿼리나 데이터 소스를 목표로 하고 있는 반면에 당신은 XQuery의 아주 단순한 부분을 사용하여 다양한 어플리케이션에서 HTML 문서들로부터 당신이 원하는 부분을 핸드폰 같이 화면 크기가 한정된 장치에서 관련 데이터를 표시할 수 있도록, 또는, 다수의 사이트에서 데이터를 모아서 표시하여 당신만의 포탈을 만들 수 있도록, Screen-Scrap할 수 있다.



XQuery로 Screen-Scraping 하기

웹 페이지를 Screen-Scraping을 위한 하나의 (또는 많은) 노력은 보통 스스로 증명할 수 없는 구조, 사이트 내에서 편집되는 컨텐츠의 구조가 변경되는 것, 또는 심지어 페이지 내에서 각각 다른 요청에 의해 추가, 삽입되는 각각 다른 동적인 컨텐츠다. 결과적으로, 당신은 응답되는 페이지의 어떤 부분이 당신이 추출하기를 원하는 데이터인지를 줄곧 생각해야만 한다.


StockPrices

Yahoo! Finance 페이지(http://finance.yahoo.com/q?s=IBM)로 부터 IBM 주식의 현재 가격을 추출해보도록 하자. 이 페이지에는 많은 정보들이 있다 -- 뉴스 헤드라인, 광고, 재정 데이터 -- 그러나 나는 "Last Trade"를 포함하는 셀 다음에 있는 주식 가격 데이터를 가지고 싶다. Listing 5의 쿼리는 "Last Trade"라는 텍스트를 포함한 모든 <td> 노드를 선택하고, 각각을 (나는 단 하나만 기대한다.) 위해, <td> 노드 이후에 나오는 컨텐츠를 포함하는 테이블 열을 출력한다. 컨텐츠들은 data() 함수에 의해 return절 내에 추출된다. 반면에, 나는 <td>노드 내의 텍스트 외에 모든 마크업을 또한 더 얻고 싶다. (이 쿼리의 교묘한 부분은 단지 text() [1] 부분이다. ; 여기서 진행되는 것은 text() 함수가 <td> 요소 내의 모든 텍스트를 매치시킨다. -- 이 경우 단지 하나 뿐이지만, XQuery는 그것을 알 수 없다. -- 그래서 나는 더욱 더 노드에 대해 텍스트 매칭을 하기 전에 먼저 첫 텍스트 노드를 선택하라고 말해야 한다.) 페이지가 페이지 내의 "Last Trade"라는 텍스트를 가진 테이블 셀을 포함하고 그 다음 셀이 주가를 포함하는 한, 페이지의 구조는 쿼리의 실패 없이 임의로 변경될 수 있다.



Weather

다른 페이지를 한번 시도해 보자. Yahoo! Weather 페이지는 많은 수의 포틀릿 패널들로 구성되어 있고 나는 리스트 된 도시들의 이름과 온도, 아이콘을 추출하고 싶다.(Yahoo! Weather 페이지(http://weather.yahoo.com)는 당신이 Yahoo!에 로그인 되어 있을경우 당신이 My Yahoo!에서 선택한 도시들의 날씨를 보여줄 것이고, 그렇지 않을 경우에는 샘플로 선택된 주요 도시들의 날씨를 보여줄 것이다.) Listing 6은 "New York, NY" 텍스트를 포함한 서브패널을 보여주고, 둘러싸인 테이블을 탐색하고, 모든 열을 선택하는 Query를 보여준다.



그러면, 각 열에 대해서, 쿼리는 관련된 세가지 데이터 행을 추출하고 -- 도시명, 온도, 아이콘 -- 이 정보들에 대해서만 간단한 테이블을 포함한 출력으로 나타낸다. 결과는 당신이 관심을 가진 도시들의 날씨 정보를 작은 화면에 맞게 간략하게 표현한다. 결과는 다음과 같다.



이 쿼리는 Listing 5의 쿼리만큼 확실하진 않다. "New York, NY"라는 텍스트는 small 요소 내부에 있다.(Yahoo!에서 다음 번에 쉽게 바뀔 수 있는 종류의 그들 페이지에서 재구성 할 마크업이다.) 또한 "New York, NY"은 날씨를 다룬 페이지에서는 한번 이상 쉽게 나타날 수 있다. 그러나, 이러한 위험 요소들은 보다 더 나은 쿼리를 개발해서 덜어낼 수 있다.; 많은 개발 옵션과 함께, 쿼리의 복잡성과, 안정성 사이의 조건이 있다.

Listing 5, Listing 6에서 보여진 쿼리들은 사용할 수 있는 쿼리들의 유일한 방법이 아니다. 좀 더 복잡한 XPath 문법을 사용하여, Listing 6에서 두개의 for절을 하나의 XPath 표현으로 넣고, Listing 5의 전부를 FLWOR 문법대신 XPath 표현처럼 사용한다. 만약 당신이 XPath 전문가라면, 당신은 아마도 XPath 지향적인 접근법을 쉽게 사용할 수 있을 것이지만, SQL에 관한 경험은 FLOWR 문법에 더욱 끌리게 할 것이다.

Tools

두드러지게 적은 양의 코드들이 HTML 페이지에 의지하여 XQuery를 실행시키는데 필요하다. JTidy 라이브러리는 HTML 문서를 깨끗하게 해주고, 그것을 DOM 오브젝트(Listing 1 참조) 형태로 표시한다. Saxon XQuery 엔진은 문서의 DOM 오브젝트에 의지하여 쿼리를 컴파일하고 실행한다. XQuery 구문을 문서의 DOM 표현에 의지하여 컴파일하고 실행하는데 Listing 7에서 보이는 것처럼 단지 6줄만 필요할 뿐이다.



쿼리 실행의 결과는 DOM 요소들의 리스트이다. 그리고 당신은 당신이 선호하는 DOM 조작 기술(당신이 가장 싫어하는 DOM 조작 기술도 괜찮다.)을 쿼리의 결과를 문서로 전환하는데 사용할 수 있다.

몇몇은 무료, 다른 몇몇은 상업적인 XQuery로 된 많은 구현 사례들이 가용하다. -- Resource를 참조하라.



종합

XQuery는 대량의 문서 기반의 쿼리로 설계되어 있는 반면에, 단순한 문서들의 변형에도 또한 좋은 툴이다. 작은 화면을 위해 복잡한 페이지를 단순화 시키거나, 집에서 만든 포탈에 많은 페이지들로 부터 요소를 추출하여 그것을 결집시키거나, 단순히 데이터를 얻기위한 프로그램적인 방법이 없기 때문에 데이터를 추출할 때, XQuery는 당신이 필요로하는 데이터들을 HTML 페이지에서 가져오는 비교적 쉬운 방법을 제공한다.

Resources
  • Participate in the discussion forum.

  • Howard Katz's An introduction to XQuery (developerWorks, June 2001) covers the basics and history of the XQuery standardization effort.

  • The tutorial, Process XML using XML Query (developerWorks, September 2002), by Nicholas Chase dives deeper into the uses and syntax ofXQuery.

  • You can read about Sam Pullara's cell phone in his blog.

  • Download JTidy from its home on SourceForge.

  • Check out the Saxon XQuery and XSL implementation.

  • You can try out the free community edition of the Mark Logic server, a content database which lets you search large document bases with XQuery.

  • The official specifications for XQuery can be downloaded from the W3C site; this page also hosts a list of XQuery implementations.

  • This set of slides from an XQuery tutorial offers a lot of good examples of what XQuery is good for and how to use it.

  • To learn more about Java technology, visit the developerWorks Java zone. You'll find technical documentation, how-to articles, education, downloads, product information, and more.

  • To learn more about XML, visit the developerWorks XML zone. As with the Java zone, you'll find technical  documentation, how-to articles, education, downloads, product information, and more.

  • Visit the New to Java technology site for the latest resources to help you get started with Java programming.

  • Get involved in the developerWorks community by participating in developerWorks blogs.

  • Browse for books on these and other technical topics.

About the author

Brian Goetz has been a professional software developer for over 18 years. He is a Principal Consultant at Quiotix, a software development and consulting firm located in Los Altos, California, and he serves on several JCP Expert Groups. See Brian's published and upcoming articles in popular industry publications.



Powered by ScribeFire.

Leave a comment
This page has been locked by password.