프로그래밍에서 많이 활용되는 코드는 어떤것들이 있을까요? 제 생각에는 대표적으로 소켓통신, DB 연결 코드 등이 있을 것 같고 오늘의 주제로 선정한 웹 파싱도 있을 것 같다라는 느낌이 듭니다.
오늘은 웹, 즉 HTML Page에 대해서 Ruby를 이용해 쉽게 파싱하고 사용하는 방법에 대해서 소개해 드릴까 합니다.
Web(HTML/XML) Parsing이란?
아주 간단한 개념입니다. Parsing이란 구문분석, 즉 형태에 대해서 어떠한 구조로 이루어져있는지 분석하는 것을 의미하는데요. 우리가 일반적으로 사용하는 웹, 즉 HTML에 대해 구조화하는 과정을 의미합니다.
그럼 웹 파싱이 왜 필요할까? 이런 의문을 가지시는 분들도 있을겁니다. 우리는 브라우저를 통해 이미지화, 프레임에 맞춰진 아주 가공된 데이터를 보고있지만 사실 브라우저로 들어오기 전 웹 페이지는 HTML 코드로 이루어진 페이지이지요.
그래서 우리는 Parsing을 통해 이 웹 페이지를 좀 더 쉽게 다룰 수 있고 구별해 낼 수 있습니다. 이 것을 위해 Web Parsing 을 하게되는거지요.
Nokogiri!
Ruby는 Java, Python 과 같이 많은 Library를 지원합니다. 그 중 단언컨데 Ruby에서 거의 최고라고 꼽는 라이브러리가 있습니다. 바로 Nokogiri 입니다. (물론 개인적인 견해입니다. 당연 웹해킹으로 밥먹고 사는데 이만한 라이브러리가 어디있겠습니까..)
웹 요청과 관련된 툴(예를들어 WVS, Crawler 등등)을 만들때 활용하면 정말 유용한 라이브러리죠.
Install Nokogiri
nokogiri를 사용하기 위해선 nokogiri gem 설치가 필요합니다. ruby-gem이 설치되어 있다면 gem 명령을 통해 쉽게 설치할 수 있습니다.
#> gem install nokogiri
** Troubleshooting ** 설치 과정 중 에러가 발생하는 경우도 있습니다. 에러에 따라 대응 방법이 대부분 다르겠지만, 공통적으로 많이 발생하는 에러에 대한 해결 방법입니다.
C 에러 #> apt-get install build-essential patch
이외 #> apt-get install ruby-dev zlib1g-dev liblzma-dev
혹시나 위 방법으로도 해결 안되는 에러가 있다면 댓글 남겨주세요.
아무튼 이제 설치가 잘 되었는지 확인해볼까요? ruby shell을 열어 nokogiri를 불러봅니다.
#> irb irb(main):001:0> require ‘nokogiri’ => true irb(main):002:0>
true 가 나온다면 정상적으로 로드된 것입니다.
Nokogiri를 이용한 HTML Parsing 1 - Load HTML/XML
nokogiri를 가지고 HTML 코드를 파싱하는 방법은 여러가지가 있습니다. 음.. 방법이라기 보단 데이터를 읽어오는 경로가 되겠네요.
- Internet으로 부터 받아오기(From the Internets) 아무래도 nokogiri가 가장 많이 사용되는 것이 원격지에서 받아 바로 파싱하는 방법일텐데요. open-uri를 이용하여 간단하게 받아올 수 있습니다.
|
|
restclient를 이용해서도 받아올 수 있겠네요.
|
|
- File로 부터 받아오기(From a File)
|
|
- 소스코드에 직접 쓰기(From a Code)
|
|
Nokogiri를 이용한 HTML Parsing 2 - CSS를 이용한 Parsing
웹 페이지를 꾸미기 위해선 CSS(Cascading Style Sheets)를 많이 사용하죠. 이 CSS는 DOM 영역안에서 각각 구역의 디자인을 담당하게 되는데 nokogiri는 이것을 이용하여 파싱할 수 있습니다.
아래 irb log를 보면 at_css를 이용해서 값을 가져오는 것을 볼 수 있습니다.
|
|
irb(main):012:0> title = page.at_css “title” => #<Nokogiri::XML::Element:0x17ac6f4 name=“title” children=[#<Nokogiri::XML::Text:0x17ac4ec “HAHWUL :: 하훌”>]>
제가 읽어온 주소의 title content 영역의 데이터가 읽어진 것을 확인할 수 있네요. 값 바꾸기 또한 굉장히 쉬운 방법으로 가능합니다.
at_css 이외에도 하나 좋은 방법이 있습니다. 개인적으로 선호하는 방법인데요, 각각 파싱된 구역은 각각 css 메소드를 가지고 있습니다.
그래서 아래와 같은 방법으로도 찾아낼 수 있습니다. 물론 위 방법이랑 거의 비슷하죠.
|
|
irb(main):032:0* page.css(“title”) => [#<Nokogiri::XML::Element:0x13d1868 name=“title” children=[#<Nokogiri::XML::Text:0x13c9ce4 “HAHWUL :: 하훌”>]>]
아래 URL에 좋은 방법이 많네요. 참고하시길!
http://ruby.bastardsbook.com/chapters/html-parsing/
Nokogiri를 이용한 HTML Parsing 3 - 태그와 id값을 가지고 찾기
제 블로그 내 HTML 코드 중 짧은것을 하나 예시로 할까합니다. 위에 시간데이터와 View 를 표기하는 영역인데요, id를 Stats1_content라고 지정해놨었습니다.
|
|
자 이제 nokogiri를 이용해서 안에 내용을 읽어와볼까요?
|
|
irb(main):040:0* page.css(“div#Stats1_content”) => [#<Nokogiri::XML::Element:0x135eb24 name=“div” attributes=[#<Nokogiri::XML::Attr:0x135eac0 name=“id” value=“Stats1_content”>, #<Nokogiri::XML::Attr:0x135eaac name=“style” value=“display: none;">] children=[#<Nokogiri::XML::Text:0x135e37c “\n”>, #<Nokogiri::XML::Element:0x135e2b4 name=“font” attributes=[#<Nokogiri::XML::Attr:0x135e228 name=“color” value=“black”>] children=[#<Nokogiri::XML::Element:0x135da6c name=“span” attributes=[#<Nokogiri::XML::Attr:0x135d8a0 name=“class” value=“hahwul count text-counter-wrapper”>, #<Nokogiri::XML::Attr:0x135d88c name=“id” value=“Stats1_totalCount”>] children=[#<Nokogiri::XML::Text:0x135cae0 “\n”>]>, #<Nokogiri::XML::Text:0x135c784 " ː Views”>]>, #<Nokogiri::XML::Text:0x135c3d8 “\n”>]>]
css를 이용해서 읽어옴과 동시에 div 안에 데이터들이 파싱된 형태로 로드되었고, 사용자는 더 상세하게 파싱해서 사용할 수도 있습니다.
Nokogiri를 이용한 HTML Parsing 4 - select 하여 직접 사용하기
이번 포스팅 내용 중 마지막 부분입니다. nokogiri는 parsing 및 검색을 통해 찾아낸 데이터에 대해 select 할 수 있고, select를 하게되면 그 데이터 내 값이나 행위들을 자유롭게 다룰 수 있게됩니다.
|
|
위와같이 css로 찾은 후 select 메소드를 사용하면 return 값으로 선택된 객체가 잡히죠. test 변수에 넣고 test 내 메소드를 통해서 값들을 호출할 수 있습니다.
irb(main):041:0> test = page.css(“div#Stats1_content”).select => #<Enumerator: [#<Nokogiri::XML::Element:0x135eb24 name=“div” attributes=[#<Nokogiri::XML::Attr:0x135eac0 name=“id” value=“Stats1_content”>, #<Nokogiri::XML::Attr:0x135eaac name=“style” value=“display: none;">] children=[#<Nokogiri::XML::Text:0x135e37c “\n”>, #<Nokogiri::XML::Element:0x135e2b4 name=“font” attributes=[#<Nokogiri::XML::Attr:0x135e228 name=“color” value=“black”>] children=[#<Nokogiri::XML::Element:0x135da6c name=“span” attributes=[#<Nokogiri::XML::Attr:0x135d8a0 name=“class” value=“hahwul count text-counter-wrapper”>, #<Nokogiri::XML::Attr:0x135d88c name=“id” value=“Stats1_totalCount”>] children=[#<Nokogiri::XML::Text:0x135cae0 “\n”>]>, #<Nokogiri::XML::Text:0x135c784 " ː Views”>]>, #<Nokogiri::XML::Text:0x135c3d8 “\n”>]>]:select> irb(main):042:0> puts test.class Enumerator => nil
맺음말
크게 nokogiri 소개와 설치방법, 3가지 단계로 사용하는 방법에 대해서 정리해봤습니다. 물론 더 많은 기능과 메소드가 존재하지만 기초적으로 꼭 알고 있어야 할 부분에 대해서 정리해봤네요. Ruby의 HTML 파싱을 담당하는 nokogiri. ruby programmer라면 잘 알아두어야겠죠?
Reference
http://www.nokogiri.org/tutorials/installing_nokogiri.html http://ruby.bastardsbook.com/chapters/html-parsing/