C# 알아가기 (6. C# 네이버 API로 뉴스 정보 받아오기)

min seung moon·2021년 8월 13일
0

C#알아가기

목록 보기
9/10
post-custom-banner

1. 네이버 API로 뉴스 정보 받아오기

01. 참고 블로그

-1. 네이버 API로 전체적인 구성과 XML 코드까지

https://ehpub.co.kr/news-crawling-library-make-csharp-data-analysis/

-2. 뉴스 데이터를 JSON으로 받아서 출력

http://www.toughman.pe.kr/2017/05/c%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%84%A4%EC%9D%B4%EB%B2%84-%EC%98%A4%ED%94%88-api-%EC%97%B0%EB%8F%99/

02. 프로젝트 준비(console project)

  • console project에서 전반적인 코드 잡고 윈도우 폼으로 확장할 예정입니다

-1. 네이버 뉴스 API Key 받기

-2. Nuget에서 Netonsoft.Json 설치

-3. (선택) API Tester

03. 프로젝트

-1. News.cs

  • Xml로 데이터를 받아왔을 때 XML을 처리해주는 메소드는 여기에 있다고 보시면 되요
  • 참고한 블로그에서는 각 필드에 set을 private으로 읽기 전용으로 했지만 Json을 Deserialize 할 때 접근이 안되서 저는 풀어 주었습니다
  • XML로만 데이터를 받으실려는 분께서는 필드의 set을 private set으로 변경해주세요!
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace NewCloling
{
    class News
    {
        public string Title { get; set; }
        public string OriginalLink{get; set;}
        public string Link { get; set; }
        public string Description { get; set; }
        public DateTime Pubdate { get; set; }

        public News(string title, string originalLink, string link, string description, DateTime pubdate)
        {
            Title = title;
            OriginalLink = originalLink;
            Link = link;
            Description = description;
            Pubdate = pubdate;
        }

        public static News Make(XmlNode xn)
        {
            try
            {
                string title = Strip(xn.SelectSingleNode("title").InnerText);
                string olink = Strip(xn.SelectSingleNode("originallink").InnerText);
                string link = Strip(xn.SelectSingleNode("link").InnerText);
                string description = Strip(xn.SelectSingleNode("description").InnerText);
                DateTime pubdate = DateTime.Parse(xn.SelectSingleNode("pubDate").InnerText);
                return new News(title, olink, link, description, pubdate);
            }
            catch
            {
                return null;
            }
        }

        private static string Strip(string innerText)
        {
            int s = innerText.IndexOf("<");
            int e = innerText.IndexOf(">");
            while(s < e)
            {
                string b = innerText.Substring(0, s);
                string a = innerText.Substring(e + 1);
                innerText = b + a;
                s = innerText.IndexOf("<");
                e = innerText.IndexOf(">");
            }
            return innerText;
        }

        public override string ToString()
        {
            return Title;
        }
    }
}

-2. NaverNews.cs

  • 이 파일에서 Naver와 연동하여 데이터를 받아오는 일을 합니다.
  • 상단에는 XML 방식과 하단에 JSON 방식으로 되어있습니다.
  • 작성하고 나니 JSON이 확실히 편하다는 생각이 많이 들었어요!
  • FindNewsJson 메서드에서 JObject를 사용한 이유는 하단에 이미지가 있는데 제가 객체 리스트로 만들 수 있는 필드 아이템외에 데이터도 있어서 필요한 데이터만 사용하기 위해서 JObject로 구분을 지어주었습니다.
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Xml;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace NewCloling
{
    class NaverNews
    {
        public string SRC { get; set; }
        public string ID { get; set; }
        public string Secret { get; set; }

        public NaverNews(string iD, string secret)
        {
            this.ID = iD;
            this.Secret = secret;
        }

        public int Find(string src)
        {
            this.SRC = src;
            Stream stream;
            string url = $"https://openapi.naver.com/v1/search/news.xml?query={SRC}&sort=date";
            XmlDocument xdoc = MakeXMLDocument(url, out stream);
            XmlNode node = xdoc.SelectSingleNode("rss");
            XmlNode n = node.SelectSingleNode("channel");
            int total = int.Parse(n.SelectSingleNode("total").InnerText);
            stream.Close();
            return total;
        }

        private XmlDocument MakeXMLDocument(string url, out Stream stream)
        {
            WebRequest request = null;
            request = WebRequest.Create(url);
            request.Headers.Add("X-Naver-Client-Id", ID);
            request.Headers.Add("X-Naver-Client-Secret", Secret);

            WebResponse response = request.GetResponse();
            stream = response.GetResponseStream();
            XmlDocument xdoc = new XmlDocument();
            xdoc.Load(stream);
            return xdoc;
        }

        public List<News> FindNewsToXML(int start, int display)
        {
            Stream stream;
            string url = $"https://openapi.naver.com/v1/search/news.xml?query={SRC}&display={display}&start={start}&sort=date";

            XmlDocument xdoc = MakeXMLDocument(url, out stream);
            XmlNode node = xdoc.SelectSingleNode("rss");
            XmlNode n = node.SelectSingleNode("channel");
            XmlNodeList xnl = n.SelectNodes("item");
            List<News> nc = new List<News>();
            News news;
            foreach(XmlNode xn in xnl)
            {
                news = News.Make(xn);
                if(news == null)
                {
                    break;
                }
                nc.Add(news);
            }
            stream.Close();
            return nc;
        }

        private string MakeJSONDocument(string url)
        {
            string responseFromServer = string.Empty;

            try
            {
                WebRequest request = WebRequest.Create(url);

                request.Method = "GET";
                request.ContentType = "application/json";
                request.Headers["X-Naver-Client-Id"] = ID;
                request.Headers["X-Naver-Client-Secret"] = Secret;

                using (WebResponse response = request.GetResponse())
                using (Stream dataStream = response.GetResponseStream())
                using (StreamReader reader = new StreamReader(dataStream))
                    responseFromServer = reader.ReadToEnd();
            }
            catch
            {
                return null;
            }

            return responseFromServer;
        }

        public List<News> FindNewsJson(int start, int display)
        {
            string url = $"https://openapi.naver.com/v1/search/news.json?query={SRC}&display={display}&start={start}&sort=date";

            var parseJson = JObject.Parse(MakeJSONDocument(url));
            
            // var QueryResultCount = Convert.ToInt32(parseJson["display"]);
            // var TotalResultCount = Convert.ToInt32(parseJson["total"]);

            List<News> news =  JsonConvert.DeserializeObject<List<News>>(parseJson["items"].ToString());

            return news;
        }
    }
}


-3. Program.cs

using System;
using System.Collections.Generic;

namespace NewCloling
{
    class Program
    {
        static void Main(string[] args)
        {
            // naver api id & scret key
            string id = "";
            string secret = "";

            NaverNews nn = new NaverNews(id, secret);
            nn.SRC = "대구";
            List<News> news = nn.FindNewsJson(1, 20);

            foreach (News ns in news)
            {
                Console.WriteLine(ns.Title);
                Console.WriteLine("==");
                Console.WriteLine(ns.Description);
                Console.WriteLine("===========================");
            }

            /*
            int total = nn.Find("코로나");
            Console.WriteLine(total);
            List<News> nc = nn.FindNewsToXML(1, 20);
            foreach(News ns in nc)
            {
                Console.WriteLine(ns.Title);
                Console.WriteLine("==");
                Console.WriteLine(ns.Description);
                Console.WriteLine("===========================");
            }
            */
        }
    }
}

04. 후기

  • 위에서 다 이야기한것 같은데 JSON이 정말 편했다 정도 인것 같다!
  • 이제 윈도우폼으로 옮길려고 하니 데이터테이블로 변환하고 귀찮을 것 같다는 생각 전에 List to DataTable 메서드를 작성해 둬서 큰 문제는 없을 것 같지만 서도 조금씩 해봐야 할 것 같다
profile
아직까지는 코린이!
post-custom-banner

0개의 댓글