본문 바로가기
프로그래밍/C#

[C#] HTML 파싱해서 원하는 정보 가져오기

by zoo10 2011. 1. 4.


System.Windows.Forms 에 있는 Browser 컨트롤을 이용하여 브라우져를 만들고 원하는 정보를 얻을 수 있습니다.(옆의 이미지를 클릭하시면 크게 보실 수 있습니다.)

이 예시는 다나와 사이트의 카드/현금 동일몰 중 가장 싼 가격을 알아내는 것으로 타겟을 정했습니다.

최저가를 MessageBox로 나타나게 하는 아주 기초적인 프로그램입니다.

이 소스는 다나와 사이트의 구조에 맞게 구성되어 있으므로 타 사이트에 적용하시길 원하시면 각각 사이트의 구조에 맞게 변형시켜야 합니다. (혹시 다나와에서 이 소스에 문제가 있으시면 말씀해 주세요. 포스트를 내리겠습니다.)

즉, 이런 것도 있다 정도로만 넘어가시면 되겠습니다.

프로젝트는 Window Form 프로젝트로 생성했습니다. 폼에 떡하니 브라우져 컨트롤 하나 딱 얹어 놨습니다. 참 볼품 없네요. ㅎㅎ;;

사실 이 코드는 HTML을 파싱하는 것에 주안점이 있습니다. 그나마 다나와 사이트의 소스가 잘 정리가 되어 있어서 DOM 객체를 사용해서 접근하기가 용이했습니다.

다나와의 카드/현금 동일몰은 HTML 태그 TABLE로 구성되어 있고 그 테이블에 ID값이 cm으로 설정되어 있습니다. 그 객체만 getElementById로 가져올 수 있으면 아주 간단하게 접근이 가능하겠죠.

소스입니다.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace testParse
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            webBrowser1.Navigate("http://blog.danawa.com/prod/?prod_c=1132675&cate_c1=861&cate_c2=873&cate_c3=959&cate_c4=0");
        }
       private void viewPrice()
        {
            HtmlDocument doc = webBrowser1.Document;
            string tableId = "cm";
            HtmlElement cm = doc.GetElementById(tableId);
            if (cm == null)
            {
                //MessageBox.Show("cm을 찾을수 없음");
                return;
            }
            HtmlElementCollection trs = cm.GetElementsByTagName("TR");
            HtmlElementCollection tds = trs[1].GetElementsByTagName("TD");
            foreach (HtmlElement el in tds)
            {
                if (el.GetAttribute("className") == "price_Point")
                {
                    el.Focus();
                    MessageBox.Show(el.InnerText);
                    break;
                }
            }
        }

        private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            if (e.Url.AbsoluteUri == webBrowser1.Url.AbsoluteUri)
                viewPrice();
        }
    }
}

몇 가지 설명을 드리면 webBrowser1_DocumentCompleted 메소드는 브라우져에 웹페이지가 모두 Load 되었을 때 발생하는 이벤트입니다. 마치 자바스크립트의 onload() 함수와 같은 역할을 한다고 보면 되는데, 이게 실제로 해보면잘 안되더군요. 페이지에 프레임이 있으면 그 수만큼 해당 메소드가 호출됩니다. 44라인의 if 문이 없으면 MessageBox가 여러번 나타납니다. 그래서 검색을 해보니 hannaming 님의 포스팅을 찾을 수 있었습니다.
여기에서 보실 수 있습니다. http://hannaming.egloos.com/1228456

이 부분을 적용해 보니 잘 되더군요. 역시 강호는 넓습니다. ^^;;

그거 외에는 특별한 게 없어 보입니다. 소스에서는 URI를 심어서 호출을 했는데 저 부분을 DB와 연동한다던가 사용자에게 입력을 받게 한다면 조금 더 나은 코딩이 될 수 있을거라고 생각됩니다.

그럼 즐프하세요~