Windows + .NET2014. 4. 11. 09:28

흔히 소프트웨어 개발 과정에서 나타나는 요구 사항들 중에서, 시간 투자 대비 효율이 가장 떨어지는 요구 사항으로 HTML 문서 분석에 대한 것이 있습니다. 이 요구 사항을 해결하기 위해서, 보통 택하는 방안으로는 Windows 환경에서 Internet Explorer의 MSHTML을 이용하는 방안을 고민하게 됩니다. 그러나 익히 알려져 있는 바, 메모리 누수나 무거운 런타임 크기, 더 나아가서는 제한된 수준의 해석 등 이점보다는 단점이 더 많은 방식이라는 것이 큰 문제입니다. 물론 이 이후로도 오픈 소스 브라우저를 활용하거나 WebKit 바인딩을 이용하는 방법도 흔히 검토가 가능하긴 하지만 전체 브라우저 스택을 완전히 불러들여야 하고 HTML 문서의 계산 과정이 동반된다는 점이 성능 상의 이슈가 됩니다.


HtmlAgilityPack은 순수하게 .NET Framework의 코드 만으로 HTML 문서를 온전하게 분석하는 것은 기본이고, System.Xml 네임스페이스에서 제공하는 XPATH 식 관련 인터페이스와 해석기를 충실하게 지원하고 있어서, 복잡하고 까다로운 HTML 문서 구조 탐색을 매우 손쉽게 처리해 준다는 큰 장점이 있습니다. 무엇보다도 중요한 것은, NuGet에서 쉽게 설치해서 사용할 수 있으므로 HTML 문서 분석에 관한 고민에 시달리고 계시다면 지금 당장 테스트해보시기를 강력히 권할 수 있을 만큼, 훌륭한 기능을 제공합니다. 강력한 기능 덕분에 몇몇 상용 솔루션에서는 이미 절찬리에 채택되어 사용 중에 있습니다.


패키지/프로젝트 소개

HtmlAgilityPack은 2014년 4월 현재 다음과 같이 두 패키지로 구분되어있습니다.

•http://www.nuget.org/packages/HtmlAgilityPack/
•http://www.nuget.org/packages/HtmlAgilityPack-PCL/

 

 

처음의 패키지는 Desktop 버전의 .NET Framework (Mono 포함)에서 이용할 수 있도록 패키징된 버전으로, XPATH 식에 대한 지원을 포함하고 있습니다. 그리고 두 번째 패키지는 Windows Phone, Windows Store App 등의 환경에서도 사용 가능하도록 Portable Class Library 프로필에 맞게 리패키징한 버전입니다. 이 글에서 설명하고자 하는 버전은 첫 번째 버전입니다.


샘플 코드

테스트하려는 프로젝트를 여신 다음, HtmlAgilityPack을 NuGet 패키지 관리자로 프로젝트에 설치하고, 실제로 HTML 페이지 분석이 잘 이루어지는지 확인해보기 위하여, 다음과 같이 코드를 작성해보도록 하겠습니다.
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml.XPath;

class Program
{
    static void Main(string[] args)
    {
        Uri targetUri = new Uri("https://www.youtube.com/watch?v=8YkbeycRa2A"); HttpWebRequest webRequest = HttpWebRequest.Create(targetUri) as HttpWebRequest;
        using (HttpWebResponse webResponse = webRequest.GetResponse() as HttpWebResponse)
        using (Stream webResponseStream = webResponse.GetResponseStream())
        {
            HtmlDocument s = new HtmlDocument();
            Encoding targetEncoding = Encoding.UTF8;

            s.Load(webResponseStream, targetEncoding, true);
            IXPathNavigable nav = s;

            string title = WebUtility.HtmlDecode(nav.CreateNavigator().SelectSingleNode("/html/head/meta[@property='og:title']/@content").ToString());
            string description = WebUtility.HtmlDecode(nav.CreateNavigator().SelectSingleNode("/html/head/meta[@property='og:description']/@content").ToString());
            string fullDescription = WebUtility.HtmlDecode(s.GetElementbyId("eow-description").InnerHtml);
            fullDescription = Regex.Replace(fullDescription, @"<(br|hr)[^>]*>", Environment.NewLine);
            fullDescription = Regex.Replace(fullDescription, @"<[^>]*>", String.Empty).Trim();

            Console.WriteLine(title);
            Console.WriteLine(description);
            Console.WriteLine(fullDescription);
        }
    }
}

여기서 설명한 코드는 YouTube의 메타 태그 속성을 이용하여 동영상에 대한 기본적인 정보를 가져오는 코드입니다. 여기서 주목할 것은 XPATH 식을 사용하여 HTML DOM 모델에 정확하게 접근하고 있다는 점입니다. Property 속성이 og:title인 META 태그의 Content 속성을 가져와서 YouTube에 정확하게 등록한 원래 동영상 제목을 추출하거나, 동영상의 설명을 같은 방법으로 가져오고 있습니다. 여기서 그치지 않고, eow-description이라는 ID를 가진 HTML 태그를 찾아 그 태그의 내용을 통째로 가져와서 축약되지 않은 원래 설명도 특별한 API 없이 가져오고 있습니다.


System.Xml.XPath 호환

위의 코드에서 HtmlDocument 클래스를 IXPathNavigable 형식의 변수 s로 캐스팅한 것을 볼 수 있습니다. 이 코드가 의미하는 바는 실로 큰데, IXPathNavigable은 .NET Framework BCL의 System.Xml 안에 들어있는 인터페이스를 실제로 대응하여 구현한 것입니다. 이 기능을 사용하면 다루는 대상이 XML이든 HTML이든 혹은 XHTML이든 일반화하여 다루는 것이 가능하여 의존성 주입의 차원을 고도화하는 것이 가능합니다.


IXPathNavigable 인터페이스는 다른 메서드를 제공하지 않고 오로지 CreateNavigator() 메서드만을 제공하는데, 이 메서드를 이용하여 만드는 객체는 XPathNavigator 클래스입니다. 이 클래스의 인스턴스는 상대적 접근 경로를 인식하여 해당 객체를 만들기 위하여 어떤 DOM 노드 객체를 활용하였는지에 따라 경로가 달라집니다. 이 기능을 사용하면 XPATH 식으로 선택이 어려운 노드를 근처의 형제 노드 (Sibling Node)를 통해서 전/후 탐색 메서드를 사용하여 접근이 가능합니다. XPathNavigator 클래스는 한 번 생성된 이후에는 자신이 스스로 상태를 관리하도록 되어있으므로 일종의 커서처럼 탐색이 가능합니다.


실제 활용 사례

이 즈음되면, 정말 특이한 상황을 제외하고 HTML 페이지를 수집하러 돌아다니는 크롤러를 얼마든지 만들 수도 있겠다는 예상도 해볼 수 있습니다. 실제로 이 라이브러리를 사용하여 크롤링 기술을 구현하고 있는 Arachnode.net이라는 Lucene.net 기반의 상용 검색 엔진 프로젝트도 많은 주목을 받고 있습니다. (http://arachnode.net/)


필자 개인적으로는 HTML 구문 분석이 필요한 프로젝트에서 상당히 큰 도움을 받았으며 해당 프로젝트의 주요 기능으로 적극적으로 채택하는데 큰 도움을 받았습니다.


도입 시 고려할 사항

HTML을 분석할 수 있다는 전무후무한 강력한 장점이 있음에도 불구하고, 한 가지 주의 사항이 있습니다. HtmlAgilityPack으로 처리할 수 있는 HTML은 파일 시스템 상의 고정된 정적 페이지나 네트워크를 통해서 서버가 정적 또는 동적으로 제공하는 HTML 페이지만 정확하게 처리가 가능하며, CSS나 JavaScript, 혹은 다른 Rich Internet Application (Flash나 Silverlight 등)이 나중에 가공하는 HTML 페이지의 변경 사항은 반영되지 않는다는 점입니다. 이것은 라이브러리의 문제가 아니며, 라이브러리가 취하고자 하는 기능의 명확한 한계입니다.


Rich Internet Application에 의한 후 처리를 제외하고 CSS나 JavaScript에 대한 처리가 완료된 웹 페이지에 대한 분석이 필요한 상황인 경우, Headless Browser를 사용하여 계산이 완료된 웹 페이지를 처리하거나 더 복잡한 작업을 수행할 수도 있습니다. 이를 위하여 PhantomJS (http://phantomjs.org/) 를 사용하는 것이 유용합니다. PhantomJS는 NuGet 패키지로도 제공됩니다. (http://www.nuget.org/packages/PhantomJS/)


만약 Rich Internet Application에 의한 후 처리까지 필요한 경우에는 Chrome이나 Internet Explorer를 해석 엔진으로 안정적으로 사용할 수 있도록 도움을 주는 Selenium Web Driver에 의한 간접적 처리도 고려해볼 수 있습니다. (NuGet 패키지: http://www.nuget.org/packages/Selenium.WebDriver/) PhantomJS와 Selenium Web Driver에 관한 이야기는 이 블로그 포스트 범위 밖에 있는 이야기이므로 존재에 대해서만 언급을 하는 것으로 갈무리하겠습니다.

 

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

남정현2014. 4. 5. 19:20
안녕하세요. Azure MVP 남정현입니다.

2014년 4월 5일부터 Tistory에서 Microsoft Azure와 Textcube 환경으로 블로그를 이사하였습니다. 도메인 주소는 그대로 유지되며 새로운 사이트로 변경되어 표시될 예정입니다.

rkttu.tistory.com으로 접속하신 분들께서는 www.rkttu.com으로 즐겨 찾기 주소를 변경하여 주시면 감사하겠습니다.



Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

Windows + .NET2014. 4. 5. 09:27

System.Net.Http.HttpClient는 ASP.NET 웹 API의 REST API 호출을 위해서도 요긴하게 사용하지만, 다양한 상황에서 사용 가능한 HTTP 송수신을 담당하는데 특화된 클래스입니다. 최근에 이 클래스를 사용하여 개발한 소프트웨어 프로젝트에서 예기치 않은 문제가 하나 있었는데, TIME_WAIT 상태로 연결 대기가 유지되는 소켓 연결의 수가 급증하여 서버에서 실행 중인 다른 데이터베이스나 웹 서비스의 연결이 WSAENOBUF WinSock 오류 코드를 반환하며 거부되는 일이었습니다.

이 클래스는 기본적으로 IDisposable 인터페이스를 구현하고 있고, 원래의 의도는 사용하지 않을 때 적시에 제거하는 것이 올바른 방식이라고 생각하였습니다. 그러나 실제로 이 클래스를 Dispose() 메서드를 사용하여 소거한다고 하더라도 클라이언트 측 연결이 끊어지지 않고 TIME_WAIT 상태로 변경되는데, 이러한 상황에서 계속 HttpClient 인스턴스를 반복적으로 만들고 연결을 다시 시도하다보면, 접속하는 클라이언트 측의 잔여 TCP 포트의 수가 부족해지는 문제가 발생하게 됩니다.

이 문제를 해결하기 위하여 취한 방법은 해당 인스턴스를 싱글턴 인스턴스로 만들어 사용하는 것이었으며, 실제로 문제를 해결할 수 있었습니다. 하지만 남아있는 문제는 이 인스턴스를 Thread-Safe 인스턴스로 만들어야 하는 것이며 이를 위해서 보강해야 할 것이 있다고 보고 있습니다.

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

이벤트2014. 2. 28. 18:09
Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요

이벤트2013. 12. 4. 13:00

안녕하세요. Windows Azure MVP 남정현입니다.

제가 현재 근무하고 있는 (주)자이닉스에서 Windows 응용프로그램 개발, Mobile 개발 및 웹 어플리케이션 부문 경력직 개발자를 채용하고 있습니다. 상세한 채용 모집 공고는 다음과 같습니다. 관심있으신 분들께서는 아래 링크를 통하여 온라인으로 지원서를 제출해주시고, 추천해 주실 만한 분이 있으시다면 역시 많은 홍보 부탁드리겠습니다.

 

㈜ 자이닉스 윈도우, 모바일, 웹 어플리케이션 
경력직 개발자 모집 채용 공고

 
자이닉스는 리치미디어 기반의 소프트웨어 개발 전문 기업으로 이러닝/프레젠테이션 콘텐츠 저작도구 및 지식 공유 플랫폼 솔루션을 개발하여, 국내 유수의 대학/기업 및 일본 시장에서 비즈니스를 전개하고 있습니다.

자이닉스는 데스크톱 기반의 어플리케이션 개발 기술, DirectX 및 Windows Media 기반의 미디어 변환 및 저작 기술, 웹 어플리케이션 개발 기술 등을 보유하고 있으며, 최근 모바일 어플리케이션 부문의 개발까지 확대하여 다양한 콘텐츠 저작 도구 및 공유 솔루션을 개발/공급하고 있습니다.


자이닉스는 윈도우, 모바일, 웹 어플리케이션 경력직 개발자 인력을 다음과 같이 채용 하고자 합니다.

관련 분야의 전문성을 가지고 새로운 영역을 개척하려는 자기 개발 의지와 도전 의지를 가지고 계신 분들의 많은 지원을 바랍니다.

Exciting

즐겁게, 신나게, 그렇지만 치열하게 일합니다.

평범하고 좋은 사람이 되기 보다, 특별한 가치를 지향하는, 세상의 변화를 꿈꾸는 회사이고자 합니다.

고객의 꿈을 실현할 수 있도록, 우리가 먼저 꿈꾸고 우리가 먼저 실천하고자 합니다.

그것이 바로 자이닉스가 말하는 Exciting입니다. 


096_110228.jpg


  1.png

Technology

이미 주어진 것을 개발하여
결과만 내는 개발자를 원하지 않습니다.

무엇을, 왜 만드는 것인지,
어떻게 만드는 것이 최선인지 고민하고,
더디더라도 사용성과 품질을 생각하여 
진정한 가치있는 상품을 만들 수 있는 개발을 지향합니다.

 다양한 웹, 윈도우 어플리케이션 기반의 디지털 커뮤니케이션 솔루션에 대한 경험을 토대로,
모바일 영역까지 확장하여,
이제는 글로벌 시장에서 겨루고자 합니다.

Companions

자이닉스 일원들이 서로 하나의
생활 공동체를 이루는 동반자입니다.

또한 우리는 고객에게 기술을 통해 가치를 전달하고, 
함께 성장해 가는 기술 동반자입니다.

같이 하기 때문에 더 큰 꿈을 이룰 수 있는
진정한 동반자가 되는 것,

그것이 자이닉스가 꿈꾸는 비전입니다.



 3.png

 


▼ 자이닉스 소개 슬라이드  (클릭해서 슬라이드를 넘겨보세요)



▼ 자이닉스 근무환경이 궁금하시다고요?


 

모집 인원
o      윈도우 및 모바일 어플리케이션 개발 부문 1~2명
o      웹 어플리케이션 개발 부문 1~2명

모집 분야

o      모바일 환경에서의 프레젠테이션 및 콘텐츠 제작 어플리케이션 개발
o      웹 기반 콘텐츠 관리 시스템(CMS) 및 서비스 플랫폼 개발


담당 업무

= 콘텐츠 제작 플랫폼(Contents Creation Platform)
           콘텐츠 제작 플랫폼은 사용자의 상황 및 의도에 가장 적합한 콘텐츠 생산 도구의 제공을 목표로 합니다.
       • 어플리케이션 개발 부문
                [Windows 및 Mobile 어플리케이션 개발 부문]
                     # 업무 영역: 윈도우 및 모바일 콘텐츠 제작용 어플리케이션 개발
                     # 전문 영역:
                               - iOS/Android 등 주류 모바일 플랫폼에 대한 어플리케이션 개발
                                        -    Objective-C, Java
                               - HTML5 기술을 이용한 어플리케이션 융합
                               - 윈도우 어플리케이션 개발
                                        -    Visual C++, C#, .NET Framework, WPF


= 콘텐츠 관리 및 서비스 플랫폼
       • 웹 CMS/서비스 플랫폼 개발 부문
                     # 업무 영역: 웹 기반 콘텐츠 관리 시스템(CMS) 및 서비스 플랫폼 개발
                     # 전문 영역:
                               - 웹 기반의 콘텐츠 관리 및 서비스 플랫폼 개발
                                        -    PHP, JavaScript, CSS, Ajax, jQuery, HTML5, XML
                               - Open CMS를 활용한 서비스 플랫폼 개발
                                        -    WordPress
                               - 클라우드 환경을 기반으로 한 웹 서비스 개발

지원 자격 조건

o      전문대 졸 이상 
o      모집 분야 및 담당 업무 관련 경력 2~3년 (*)  

심사 시 주안점 및 우대 조건

o      관련 업무에 대해 적극적인 참여를 통한 개발 경험이 있으신 분
o      활발한 커뮤니케이션에 익숙하고 팀 단위 활동에 적극적이신 분
o      영어, 일본어 등 외국어 능통자 우대
 
근무 조건 및 복리후생

o      연봉 - 사내 규정에 따름, 퇴직금 별도
o      주 5일 (월~금) 근무, 연차 12일
o      4대 보험 (국민연금, 고용보험, 산재보험, 건강보험), 퇴직금
o      각종 경조금, 경조 휴가
o      우수 사원 포상
o      도서구입비 지원
o      역량 강화를 위한 교육, 세미나, 전시회 등 적극 지원

전형 절차
 
o      1차: 서류 전형 (1차에 합격하신 분에 한해서 개별 통보)
o      2차: 기술 면접
o      3차: 인성 면접
o      4차: 최종 면접

제출 서류

o      이력서 (연락처/사진 포함) 및 자기소개서 
        ※  이력서는 제공해 드리는 양식을 참고해 주시고, 자기소개서는 자유 양식으로 작성하시기 바랍니다.
             (이력서 양식 다운로드 - http://link.rkttu.com/xinics-resume-form)
o      경력 및 참여 부문별 개발 경험 및 관심사 위주로 작성 

접수 방법

o      이메일 접수 : recruit@xinics.com 

전형 일정

o      서류 접수: 채용 완료 전 까지
o      서류 전형 결과 발표: 서류 접수 후 서류 심사 통과자에게 개별 통보
o      면접: 서류 심사 합격자 개별 연락하여 일정 확인
        ※ 지원자 규모 및 여부에 따라 변동 가능

문의 및 연락처

o      이메일 : recruit@xinics.com
o      전화: 02-2109-8801 (311)
o      담당자: 박진궁 차장
 
회사 위치 

o      서울시 구로구 구로동 197-22 에이스테크노타워 5차 610호 (주)자이닉스
o      회사로 오시는 길 (네이버 지도) - http://link.rkttu.com/xinics-map 

Posted by Cloud Developer 남정현 (rkttu.com)

댓글을 달아 주세요